您好,登錄后才能下訂單哦!
今天小編給大家分享一下JS中ESModule和commonjs的使用區別是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
named exports: 命名導出,每次可以導出一個或者多個。
default exports: 默認導出,每次只能存在一個。
以上兩者可以混合導出:
// 命名導出 export const b = 'b' // 默認導出 export default { a: 1 }; const c = 'c' export { c } // 以上內容會合并導出,即導出為: {b:'b', c:'c', default: {a:1}}
更多示例可以直接去看mdn
算是一個導入再導出的一個語法糖吧。
export { default as function1, function2, } from 'bar.js'; // 等價于 import { default as function1, function2 } from 'bar.js'; export { function1, function2 };
然而這種語法是會報錯的:
export DefaultExport from 'bar.js'; // Invalid
正確的語法應該是:
export { default as DefaultExport } from 'bar.js'; // valid
我猜是因為export 本身支持的export xxx這種語法必須是要導出一個對象,然而import xxx可能是任意類型,兩者沖突了,所以從編譯層面就不讓這種語法生效會更好。
嵌入式腳本不可以使用export。
import all exports: import * as allVar
,所有導出內容,包含命名導出及默認導出。allVar會是一個對象,默認導出會作為allVar的key名為default對應的值。
import named exports: import {var1, var2}
,引入命名導出的部分。沒找到,對應的值就為undefined。個人覺得可以看做是"import all exports"的解構語法。
import default exports: import defaultVar
,引入默認導出的部分。
import side effects: import "xxx./js"
,僅運行這個js,可能是為了獲取其副作用。
// test.js export const b = 'b' // 命名導出 export default { // 默認導出 a: 1 }; // index.js import { b, default as _defaultModule } from './test.js' import defaultModule from './test.js' import * as allModule from './test.js' console.log('name export', b) // 'b' console.log('default export', defaultModule) // {a:1} console.log(_defaultModule === defaultModule) // true console.log('all export', allModule) // {b:'b', default: {a:1}}
一個之前老記錯的case
// test.js export default { // 默認導出 a: 1 }; // index.js import { a } from './test.js' console.log('name export', a) // undefined // index.js import defaultModule from './test.js' import * as allModule from './test.js' console.log('default export', defaultModule) // {a:1} console.log('all export', allModule) // {default: {a:1}}
嵌入式腳本引入modules時,需要在script上增加 type="module"。
live bindings:
通過export在mdn上的解釋,export導出的是live bindings,再根據其他文章綜合判斷,應該是引用的意思。即export導出的是引用。
模塊內的值更新了之后,所有使用export導出值的地方都能使用最新值。
read-only:通過import在mdn上的解釋,import使用的是通過export導出的不可修改的引用。
strict-mode:被引入的模塊都會以嚴格模式運行。
靜態引入、動態引入
import x from
這種語法有syntactic rigid,需要編譯時置于頂部且無法做到動態引入加載。如果需要動態引入,則需要import ()
語法。有趣的是,在mdn上,前者分類到了 Statements & declarations, 后者分類到了 Expressions & operators。這倆是根據什么分類的呢?
true && import test from "./a.js"; // SyntaxError: import can only be used in import() or import.meta // 這里應該是把import當成了動態引入而報錯
示例:
// a.js const test = { a: 1 }; export default test; // 改動模塊內部的值 setTimeout(() => { test.a = 2; }, 1000); // index.js import test from './index.js' /* live bindings */ console.log(test) // {a:1} setTimeout(()=>{ console.log(test) // {a:2} }, 2000) /* read-only */ test= { a: 3 } // 報錯, Error: "test" is read-only. /* syntactically rigid */ if(true){ import test from './index.js' // 報錯, SyntaxError: 'import' and 'export' may only appear at the top level }
在 Node.js 模塊系統中,每個文件都被視為獨立的模塊。模塊導入導出實際是由nodejs的模塊封裝器實現,通過為module.exports
分配新的值來實現導出具體內容。
module.exports
有個簡寫變量exports
,其實就是個引用復制。exports作用域只限于模塊文件內部。 原理類似于:
// nodejs內部 exports = module.exports console.log(exports, module.exports) // {}, {} console.log(exports === module.exports) // true
注意:nodejs實際導出的是module.exports,以下幾種經典case單獨看一下:
case1:
// ?使用exports exports.a = xxx console.log(exports === module.exports) // true // ?等價于 module.exports.a = xxx
case2:
// ?這么寫可以導出,最終導出的是{a:'1'} module.exports = {a:'1'} console.log(exports, module.exports) // {}, {a:'1'} console.log(exports === module.exports) // false // ?不會將{a:'1'}導出,最終導出的是{} exports = {a:'1'} console.log(exports, module.exports) // {a:'1'}, {} console.log(exports === module.exports) // false
通過require語法引入:
// a是test.js里module.exports導出的部分 const a = require('./test.js')
原理偽代碼:
function require(/* ... */) { const module = { exports: {} }; ((module, exports) => { // Module code here. In this example, define a function. function someFunc() {} exports = someFunc; // At this point, exports is no longer a shortcut to module.exports, and // this module will still export an empty default object. module.exports = someFunc; // At this point, the module will now export someFunc, instead of the // default object. })(module, module.exports); return module.exports; }
// test.js let test = {a:'1'} setTimeout(()=>{ test = {a:'2'} },1000) module.exports = test // index.js const test1 = require('./test.js') console.log(test1) // {a:1} setTimeout(()=>{ console.log(test1) // {a:1} },2000)
語法:
exports
、module.exports
和require
是Node.js模塊系統關鍵字。
export
、export default
和import
則是ES6模塊系統的關鍵字:
原理:
exports
、module.exports
導出的模塊為值復制。
export
、export default
為引用復制。
時機:
ES Module靜態加載是編譯時確定,ES Module動態加載是運行時確定。
CommonJS是運行時確定。
以上就是“JS中ESModule和commonjs的使用區別是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。