[Node] CommonJS Modules and ES Modules
- Modules: CommonJS modules @ node.js
- Modules:ECMAScript modules @ node.js
- Understanding module.exports and exports in Node.js @ SitePoint
ES Modules
keywords: .mjs
, .cjs
在 NodeJS 13 之後支援 ESModules 的寫法,使用前需要進行前置作業,方法包括下述兩種:
- 改變整個專案的預設值:在
package.json
中加入{ "type": "module" }
,這時候全部的檔案都會套用 ESModules - 針對單一檔案:有些時候,可能會希望直接指定某檔案所使用的 module system,這時候可以透過「副檔名」來達到忽略 package.json 中
type
設定的效果。如果該檔案需要使用 Common JS 的話,可以把原本的.js
改成.cjs
;如果該檔案需要使用 ES Module 的話,這可以把原本的.js
改成.mjs
提示
可以想成副檔名改成 .mjs
或 .cjs
的情況下,能夠 override 掉 package.json
中 type
的設定。
要特別留意的是,如果使用了 ES Module,則:
- 在 import 模組時,路徑的部分需要把完整的副檔名寫出來,例如:
// 如果在 package.json 中使用 { "type": "module" }
import { sum } from './math.js';
// 如果使用的是副檔名為 .mjs
import { sum } from './math.mjs';
- 在 ES modules 中可以 import CommonJS modules;但如果在 CommonJS 中要 import ES Modules 的話,則需要使用 dynamic import。
CommonJS Modules
匯入與匯出變數
// 匯出
exports.foo = 'foo';
exports.bar = 'bar';
// 匯入
const cjs = require('./modules'); // { foo: 'foo', bar: 'bar' }
等價於下面的寫法:
// 匯出
// Common JS 匯出的是「物件」,所以可以使用 key-value pair
module.exports = {
foo: 'foo',
bar: 'bar',
};
// 匯入
const cjs = require('./modules'); // { foo: 'foo', bar: 'bar' }
匯出與匯入函式
// greet.js
function greet() {
console.log('Hello');
}
greet();
module.exports = greet;
// app.js
const greet = require('./greet');
greet(); // 可以使用
或者
// 匯出
const sum = (a, b) => a + b;
const multiply = (a, b) => a + b;
module.exports.sum = sum;
module.exports.multiply = multiply;
module.exports = { sum, multiply };
// 匯入
const math = require('./math');
const sum = require('./math').sum;
const multiply = require('./math').multiply;
math.sum(3, 5);
math.multiply(3, 5);
沒有匯出的函式無法使用
// greet.js
function greet() {
console.log('Hello');
}
greet();
執行 app.js 時會出現 'Hello',但是在 app.js 中並沒有辦法呼叫到 greet() 這個函式
// app.js
require('./greet');
greet(); // ReferenceError: greet is not defined