JS中ESModule和commonjs介绍及使用区别

JS中ESModule和commonjs介绍及使用区别
最新回答
薄凉的只是时光

2023-09-03 14:35:03

ES Module导出仅支持命名导出(named exports)和默认导出(default exports)。可以混合导出,例如:

javascript
export const b = 'b'
export default { a: 1 }
const c = 'c'
export { c }

这将合并导出为一个对象:{b:'b', c:'c', default: {a:1}}。

重导出(re-exporting / aggregating)是一种导入再导出的语法糖:

javascript
export { default as function1, function2 } from 'bar.js'

等价于:

javascript
import { default as function1, function2 } from 'bar.js'
export { function1, function2 }

错误的语法:

javascript
export DefaultExport from 'bar.js' // Invalid

正确的语法:

javascript
export { default as DefaultExport } from 'bar.js' // valid

嵌入式脚本引入模块时需要在script上添加type=module:

嵌入式脚本特点:

live bindings:ES Module导出的是live bindings,即引用。模块内的值更新后,所有使用export导出值的地方也会更新。

read-only:import导入的是不可修改的引用。

strict-mode:引入的模块将以严格模式运行。

静态引入、动态引入:

静态引入通过import语法,需编译时置于顶部,无法动态加载。动态引入需使用import()语法。

示例:

javascript
const test = { a: 1 }
export default test
setTimeout(() => { test.a = 2; }, 1000)

javascript
import test from './index.js'
console.log(test) // {a:1}
setTimeout(() => { console.log(test) // {a:2} }, 2000)

javascript
test = { a: 3 } // 报错, Error: "test" is read-only

javascript
if(true){ import test from './index.js' // 报错, SyntaxError: 'import' and 'export' may only appear at the top level

CommonJS导出:

Node.js模块系统中,每个文件视为独立模块。模块导入导出由Node.js的模块封装器实现,通过为module.exports分配新值来导出内容。module.exports有简写变量exports,即引用复制。

示例:

javascript
exports.a = xxx

等价于:

javascript
module.exports.a = xxx

javascript
module.exports = {a:'1'}

不会将{a:'1'}导出,最终导出的是{}:

javascript
exports = {a:'1'}

引入通过require语法:

javascript
const a = require('./test.js')

CommonJS特点:值拷贝。

ES Module和CommonJS区别:

语法:ES Module使用export、export default和import;CommonJS使用exports、module.exports和require。

原理:ES Module导出为引用复制,CommonJS导出为值复制。

时机:ES Module静态加载在编译时确定,动态加载在运行时确定;CommonJS在运行时确定。