當前端應用越來越複雜時,我們想要將**分割成不同的模組,便於復用、按需載入等。
require 和 import 分別是不同模組化規範下引入模組的語句,下文將介紹這兩種方式的不同之處。
年份出處
require/exports
2009
commonjs
import/export
2015
ecmascript2015(es6)
require/exports
import/export
node.js
所有版本
node 9.0+(啟動需加上 flag --experimental-modules)node 13.2+(直接啟動)
chrome
不支援61+
firefox
不支援60+
safari
不支援10.1+
edge
不支援16+
commonjs 模組化方案 require/exports 是為伺服器端開發設計的。伺服器模組系統同步讀取模組檔案內容,編譯執行後得到模組介面。(node.js 是 commonjs 規範的實現)。
在瀏覽器端,因為其非同步載入指令碼檔案的特性,commonjs 規範無法正常載入。所以出現了 requirejs、seajs 等(相容 commonjs )為瀏覽器設計的模組化方案。
兩種方案各有各的限制,需要注意以下幾點:
commonjs 載入的是乙個物件(即 module.exports 屬性),該物件只有在指令碼執行完才會生成。而 es6require/exports 輸出的是值的拷貝。也就是說,一旦輸出乙個值,模組內部的變化就影響不到這個值。模組不是物件,它的對外介面只是一種靜態定義,在**靜態解析階段就會生成。- 阮一峰
import/export 模組輸出的是值的引用。js 引擎對指令碼靜態分析的時候,遇到模組載入命令import,就會生成乙個唯讀引用。等到指令碼真正執行時,再根據這個唯讀引用,到被載入的那個模組裡面去取值。
若檔案引用的模組值改變,require 引入的模組值不會改變,而 import 引入的模組值會改變。
const fs = require(『fs』)exports 是對 module.exports 的引用,相當於exports.fs = fs
module.exports = fs
exports = module.exports = {};在不改變 exports 指向的情況下,使用 exports 和 module.exports 沒有區別;如果將 exports 指向了其他物件,exports 改變不會改變模組輸出值。示例如下:
let a = 100;(2). import/export 的寫法exports.a = 200;
console.log(module.exports) //
exports = ; //exports 指向其他記憶體區
var a = require(』./utils』);
console.log(a) // 列印為
import fs from 『fs』import from 『fs』 //從 fs 匯入 readfile 模組
import from 『fs』 //從 fs 中匯入使用 export default 匯出的模組
import * as filesystem from 『fs』 //從 fs 匯入所有模組,引用物件名為 filesystem
import from 『fs』 //從 fs 匯入 readfile 模組,引用物件名為 read
export default fs
export const fs
export function readfile
export
export * from 『fs』
建議1:建議明確列出我們要引用的內容。,使用 * 雖然很方便,但是不利於現代的構建工具檢測未被使用的函式,影響**優化。 同時需要注意1.引入 export default 匯出的模組不用加 {},引入非 export default 匯出的模組需要加 {}。
import filesystem, from 『fs』2.乙個檔案只能匯出乙個 default 模組。
3. 在驗證**的時候遇到如下報錯
access to script from origin 『null』 has been blocked by cors policy前面提到過,瀏覽器引入模組的 元素要新增 type="module 屬性,但 module 不支援 ftp 檔案協議(file://),只支援 http 協議,所以本地需要使用 http-server 等本地網路伺服器開啟網頁檔案。
(3). import/export 不能對引入模組重新賦值/定義
當我嘗試給 import 的模組重新賦值時
import from 『./webutils.js』;瀏覽器顯示e1=234;
uncaught typeerror: assignment to constant variable.當我重新定義引用的模組
import from 『./webutils.js』;瀏覽器顯示var e1=1;
(index):17 uncaught syntaxerror: identifier 『e1』 has already been(4). es6 模組可以在 import 引用語句前使用模組,commonjs 則需要先引用後使用declared
es6 模組
程式報錯export var e=『export』;
console.log(e) //export
import from 『./webutils.js』;
console.log(e) //export commonjs
exports.e = 『export』;
console.log(a)
a = require(』./utils』);
console.log(a)
referenceerror: a is not defined(5)import/export 只能在模組頂層使用,不能在函式、判斷語句等**塊之中引用;require/exports 可以。
import fs from 『./webutils.js』;程式報錯function a() from './webutils.js';
console.log(e1)
}a();
console.log(fs())
uncaught syntaxerror: unexpected token 『;export default fun;7.其他模組化方法require/exports 預設不使用嚴格模式,可以自定義是否使用嚴格模式。 例如
exports.fun = ()=>;
動態匯入
import(modulepath) 表示式載入模組並返回乙個 promise,該 promise resolve 為乙個包含其所有匯出的模組物件。
我們可以在**中的任意位置動態地使用它。例如:
import(』/modules/my-module.js』) //動態匯入建議: 請不要濫用動態匯入 import()(只有在必要情況下採用)。靜態框架能更好的初始化依賴,而且更有利於靜態分析工具和 tree shaking 發揮作用.then((module) => );
import和require的區別
node程式設計中最重要的思想就是模組化,import和require都是被模組化所使用。遵循規範 呼叫時間 本質 require exports 遵循 commonjs amd,只能在執行時確定模組的依賴關係及輸入 輸出的變數,無法進行靜態優化。用法只有以下三種簡單的寫法 const fs req...
import和require的區別
遵循規範 require 是 amd規範引入方式 import是es6的乙個語法標準,如果要相容瀏覽器的話必須轉化成es5的語法 呼叫時間 require是執行時呼叫,所以require理論上可以運用在 的任何地方 import是編譯時呼叫,所以必須放在檔案開頭 本質require是賦值過程,其實r...
import和require的區別
node程式設計中最重要的思想就是模組化,import和require都是被模組化所使用。遵循規範 require 是 amd規範引入方式 import是es6的乙個語法標準,如果要相容瀏覽器的話必須轉化成es5的語法呼叫時間 require是執行時呼叫,所以require理論上可以運用在 的任何地...