js中關(guān)于require與import的區(qū)別及說明
require和import的區(qū)別
起源
es6誕生之前,js一直沒有模塊系統(tǒng),就連css都有@import,對現(xiàn)在復(fù)雜的大型項目開發(fā)無疑是一種阻礙。
es6在2015年6月正式發(fā)布,所以es6也有一個別稱es2015。官方?jīng)]有提出es6之前,社區(qū)給出了解決模塊問題的方案,那就是node.js。
介紹到這個地方,其實require和import的起源已經(jīng)出現(xiàn)了,es6中模塊解決方案使用的關(guān)鍵字是import,而node.js提供的解決方案使用的關(guān)鍵字是require。
node.js由Ryan Dahl在2009年發(fā)布。node.js提供的模塊化也叫CommonJS,不過node.js主要用于服務(wù)端的開發(fā),但是隨著時代的發(fā)展,現(xiàn)在的一些前端框架也依賴node.js
導出命令/引入命令
要想使用require或者import,首先得知道使用這兩種方式對應(yīng)的導出方式是怎樣的,從現(xiàn)在開始,下文分別以CommonJS和es6來區(qū)分兩種解決方案。
CommonJS
導出變量,方法,對象
// testcommonjs.js
exports.a = 123;
exports.b = 'hello';
exports.c = function(){
? console.log('ccc')
}
exports.d = {
? foo: 'bar'
}
//等價=>?
module.exports.a = 123;
module.exports.b = 'hello';
//等價=>?
module.exports = {
? a:123,
? b:'hello',
? c:function(){
? ? console.log('ccc')
? },
? d:{
? ? foo:bar
? }
}建議使用module.exports,單獨使用exports在某些情況下會產(chǎn)生意想不到的錯誤,這不是本文討論的重點
引入和使用
//index.js
var test = require('./testcommonjs')
console.log(test.a)
console.log(test.b)
test.c()
console.log(test.d.foo)es6
導出變量,方法,對象(這里只列舉常用的一些方法,具體的使用方法請參考阮一峰es6入門)
//testesmodule.js
export var a = 123
export var b = 'hello'
export function c(){
? console.log('ccc')
}
export var d = {
? foo: 'bar'
}引入和使用
import { a,b,c,d } from './testesmodule'
console.log(a)
console.log(b)
c()
console.log(d.foo)
//等價=>?
import * as test form './testesmodule'
console.log(test.a)
console.log(test.b)
test.c()
console.log(test.d.foo)靜態(tài)優(yōu)化
這是從阮一峰大神的文檔中學習到的一個概念。他在文檔中以node的核心模塊fs舉了一個例子
es6
// ES6模塊
import { stat, exists, readFile } from 'fs';注:不要試圖在沒有配置babel的項目中去測試上面的代碼,因為node到目前為止依然不支持es6的模塊化語法(筆者目前的node版本:v10.15.0),盡管它已經(jīng)實現(xiàn)了絕大部分的es6特性。
CommonJS
// CommonJS模塊
let { stat, exists, readFile } = require('fs');這樣看起來,fs模塊的引入方式在es6中和CommonJS中似乎只是語法上的區(qū)別,但是實際上,在CommonJS中上述代碼的處理方式是這樣的
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;也就是說,為了使用fs中的stat、exists、readFile方法,在代碼執(zhí)行使必須把fs整個模塊全部加載進來,生成一個對象_fs,然后再從這個對象上面讀取3個方法,這種加載被稱為“運行時加載”,因為只有運行時才能得到這個對象。
而es6模塊的設(shè)計思想是盡量的靜態(tài)化,使得編譯時就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量,從這個角度上來看,es6的模塊化效率要比CommonJS高得多。阮一峰大神在文檔中還列舉了一些靜態(tài)加載的其他優(yōu)點,但是本菜鳥并不能看懂╮(╯▽╰)╭
新的思考:
fs是node.js的核心模塊,為什么es6的模塊化語法能夠生效,在ws中通過文件定位,發(fā)現(xiàn)node.js的核心模塊代碼全是用ts寫的,但是由于對ts語法不太熟悉,無法理解ts是如何能夠做到既兼容CommonJS又兼容es6的。
(com)require和import,動態(tài)和靜態(tài)
require和import的區(qū)別問題
require用于讀取并執(zhí)行js文件, 并返回該模塊的exports對象, 若無指定模塊, 會報錯。CommonJS規(guī)范加載模塊是同步且動態(tài)的, 只有加載完成, 才能執(zhí)行后續(xù)操作??梢栽诖a中引入
import用于引入外部模塊, 其他腳本等的函數(shù), 對象或者基本類型。
import屬于ES6的命令, 它和require不一樣, 它會生成外部模塊的引用而不是加載模塊,等到真正使用到該模塊的時候才會去加載模塊中的值。
動態(tài)引入和靜態(tài)引入
webpack支持node的commonJS標準,而且它的require實現(xiàn)和node極為類似;所以將node的require和webpack的require放在一起講:
而且因為vue用了webpack,所以在vue中webpack的require也可以使用;
require是動態(tài)引入,因為他是運行時調(diào)用,可以放在代碼的任何位置。
使用webpack的require需注意:
let url = "@/assets/images/carousel/logo.svg"
require(url) ? ?//報錯
let url = "logo.svg"
require("@/assets/images/carousel/"+url); //正確不能直接給require變量,要給require一個初始的地址,具體的文件名給變量,以方便遍歷
而import支持靜態(tài)引入和動態(tài)引入兩種:
1.靜態(tài)引入
import { a, b, c } from "./a";2.動態(tài)引入
if (condition) {
? import('moduleA').then(...);
} else {
? import('moduleB').then(...);
}PS1:區(qū)分靜態(tài)和動態(tài)
靜態(tài)是按照文件的嵌套關(guān)系找到文件或者分析代碼,不需要運行
動態(tài)與執(zhí)行順序有關(guān),會在執(zhí)行的過程中根據(jù)變化進行一些操作
PS2:node中兩種導出方式的區(qū)別
1.置換exports整個對象
module.exports = {} ??
const lib = require("xxx")2.不置換,只是編輯exports,加屬性,這個aaa就是key
exports.aaa === module.exports.aaa
exports.aaa = 123
const {aaa} = require("xxx")無論時哪種,最后返回的都是exports對象,都可以通過鍵值從里邊拿值
PS3:ES6中兩種導出方式的區(qū)別
1.export
export ? func1=()=>{}
export ? func2=()=>{}
import { func1, func2 } from 'xxx';2.export default
export default class Example{}
import Example from "xxx"以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript之瀏覽器對象_動力節(jié)點Java學院整理
JavaScript可以獲取瀏覽器提供的很多對象,并進行操作。下面通過本文給大家介紹JavaScript之瀏覽器對象的相關(guān)知識,一起看看吧2017-07-07
淺談JavaScript 數(shù)據(jù)屬性和訪問器屬性
下面小編就為大家?guī)硪黄獪\談JavaScript 數(shù)據(jù)屬性和訪問器屬性。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09
淺析JavaScript Array和string的轉(zhuǎn)換(推薦)
下面小編就為大家?guī)硪黄獪\析JavaScript Array和string的轉(zhuǎn)換(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05
使用mock.js隨機數(shù)據(jù)和使用express輸出json接口的實現(xiàn)方法
這篇文章主要介紹了使用mock.js隨機數(shù)據(jù)和使用express輸出json接口的實現(xiàn)方法,需要的朋友可以參考下2018-01-01

