CommonJS模塊加載方法


一、 ES6 模塊與 CommonJS 模塊的差異

有三個重大差異

1、CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。

2、CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。

3、CommonJS 模塊的require()是同步加載模塊,ES6 模塊的import命令是異步加載,有一個獨立的模塊依賴的解析階段。

1、第一個差異解釋:

CommonJS 模塊輸出的是值的拷貝,也就是說,一旦輸出一個值,模塊內部的變化就影響不到這個值。
例子:
// lib.js
var counter = 3;
function incCounter() {
  counter++;
}
module.exports = {
  counter: counter,
  incCounter: incCounter,
};

// main.js
var mod = require('./lib');

console.log(mod.counter);   // 3
mod.incCounter();
console.log(mod.counter);   // 3

lib.js模塊加載以后,它的內部變化就影響不到輸出的mod.counter了。
這是因為mod.counter是一個原始類型的值,會被緩存,除非寫成一個函數,才能得到內部變動后的值。
module.exports = {
  get counter() {
    return counter
  },
  incCounter: incCounter,
};
ES6 則相反,原始值變了,import加載的值也會跟着變。

2、第二個差異解釋:
因為 CommonJS 加載的是一個對象(即module.exports屬性),該對象只有在腳本運行完才會生成。
而 ES6 模塊不是對象,它的對外接口只是一種靜態定義,在代碼靜態解析階段就會生成。



node.js 模塊加載方法

CommonJS 模塊是 Node.js 專用的,與 ES6 模塊不兼容。

1、語法上面,兩者最明顯的差異是,CommonJS 模塊使用require()和module.exports,ES6 模塊使用import和export。

2、從 Node.js v13.2 版本開始,Node.js 已經默認打開了 ES6 模塊支持。
3、Node.js 要求 ES6 模塊采用.mjs后綴文件名。也就是說,只要腳本文件里面使用import或者export命令,那么就必須采用.mjs后綴名。

4、Node.js 遇到.mjs文件,就認為它是 ES6 模塊,默認啟用嚴格模式,不必在每個模塊文件頂部指定"use strict"。

5、如果不希望將后綴名改成.mjs,可以在項目的package.json文件中,指定type字段為module。
6、一旦設置了以后,該目錄里面的 JS 腳本,就被解釋用 ES6 模塊。

7、如果這時還要使用 CommonJS 模塊,那么需要將 CommonJS 腳本的后綴名都改成.cjs

8、如果沒有type字段,或者type字段為commonjs,則.js腳本會被解釋成 CommonJS 模塊

9、注意,ES6 模塊與 CommonJS 模塊盡量不要混用

CommonJS 的一個模塊,就是一個腳本文件。require命令第一次加載該腳本,就會執行整個腳本,
然后在內存生成一個對象。
{
  id: '...',
  exports: { ... },
  loaded: true,
  ...
}
上面代碼就是 Node 內部加載模塊后生成的一個對象
id屬性是模塊名
exports屬性是模塊輸出的各個接口
loaded屬性是一個布爾值,表示該模塊的腳本是否執行完畢
以后需要用到這個模塊的時候,就會到exports屬性上面取值。即使再次執行require命令,也不會再次執行該模塊,而是到緩存之中取值
也就是說,CommonJS 模塊無論加載多少次,都只會在第一次加載時運行一次,以后再加載,就返回第一次運行的結果,除非手動清除系統緩存。


// 導入
var util =  require('/utils.js');

//導出;
module.exports = {
    counter: counter,
    incCounter: incCounter,
};

三、package.json 的 main 字段

package.json文件有兩個字段可以指定模塊的入口文件:main和exports。比較簡單的模塊,
可以只使用main字段,指定模塊加載的入口文件。
{
  "type": "module",
  "main": "./src/index.js"
}

上面代碼指定項目的入口腳本為./src/index.js,它的格式為 ES6 模塊。
如果沒有type字段,index.js就會被解釋為 CommonJS 模塊。

參考https://es6.ruanyifeng.com/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM