在Node.js中,模塊系統主要有兩種:CommonJS(CJS)和ECMAScript Modules(ESM)。這兩種模塊系統在語法、加載方式、兼容性等方面存在顯著差異。本文將詳細探討CJS與ESM的不同點。
CommonJS是Node.js最早采用的模塊系統,使用require
和module.exports
來導入和導出模塊。
// 導出模塊
module.exports = {
foo: 'bar'
};
// 導入模塊
const myModule = require('./myModule');
console.log(myModule.foo); // 輸出: bar
ESM是JavaScript的標準模塊系統,使用import
和export
來導入和導出模塊。
// 導出模塊
export const foo = 'bar';
// 導入模塊
import { foo } from './myModule.js';
console.log(foo); // 輸出: bar
CJS是同步加載模塊的,這意味著模塊在require
時會被立即加載和執行。
const fs = require('fs');
const data = fs.readFileSync('./file.txt', 'utf8');
console.log(data);
ESM是異步加載模塊的,這意味著模塊在import
時會被異步加載和執行。
import { readFile } from 'fs/promises';
async function readData() {
const data = await readFile('./file.txt', 'utf8');
console.log(data);
}
readData();
CJS模塊通常使用.js
作為文件擴展名。
// myModule.js
module.exports = {
foo: 'bar'
};
ESM模塊通常使用.mjs
作為文件擴展名,或者在package.json
中指定"type": "module"
。
// myModule.mjs
export const foo = 'bar';
或者在package.json
中指定:
{
"type": "module"
}
CJS是Node.js的默認模塊系統,因此在所有版本的Node.js中都得到支持。
ESM在Node.js 12及以上版本中得到支持,但在某些情況下可能需要額外的配置或使用.mjs
擴展名。
CJS支持動態導入,可以通過require
在運行時動態加載模塊。
const moduleName = './myModule';
const myModule = require(moduleName);
console.log(myModule.foo);
ESM也支持動態導入,但需要使用import()
函數。
const moduleName = './myModule.js';
import(moduleName).then(myModule => {
console.log(myModule.foo);
});
await
CJS不支持頂層await
,必須在異步函數中使用await
。
async function main() {
const data = await someAsyncFunction();
console.log(data);
}
main();
ESM支持頂層await
,可以在模塊的頂層直接使用await
。
const data = await someAsyncFunction();
console.log(data);
CJS模塊解析是基于文件路徑的,require
會按照Node.js的模塊解析規則查找模塊。
const myModule = require('./myModule');
ESM模塊解析是基于URL的,import
會按照ESM的模塊解析規則查找模塊。
import { foo } from './myModule.js';
CJS支持默認導出,可以通過module.exports
導出單個值。
module.exports = 'bar';
ESM也支持默認導出,可以通過export default
導出單個值。
export default 'bar';
CJS在處理循環依賴時可能會導致部分模塊未完全加載。
// a.js
const b = require('./b');
console.log('a:', b);
// b.js
const a = require('./a');
console.log('b:', a);
ESM在處理循環依賴時更加健壯,能夠正確處理未完全加載的模塊。
// a.mjs
import { b } from './b.mjs';
console.log('a:', b);
// b.mjs
import { a } from './a.mjs';
console.log('b:', a);
CJS是同步加載的,因此在加載大量模塊時可能會導致性能問題。
ESM是異步加載的,因此在加載大量模塊時性能更好。
CJS和ESM在Node.js中各有優缺點。CJS是Node.js的傳統模塊系統,兼容性好,但同步加載可能導致性能問題。ESM是JavaScript的標準模塊系統,支持異步加載和頂層await
,但在某些情況下需要額外的配置。根據項目需求選擇合適的模塊系統是非常重要的。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。