common js
require 函数的原理伪代码:
function require(path) {
if (该模块有缓存) {
return 该模块的缓存
}
function _run(exports, require, module, __filename, __dirname) {
// 模块代码
}
// module.exports 即为模块导出的对象
var module = { exports: {} };
_run.call(module.exports, module.exports, require, module, __filename, __dirname);
// 将 module.exports 加入缓存
return module.exports;
}
console.log(arguments.length) // 5 // 刚好是 _run 的五个参数
console.log(this) // {}
使用require:
const m = require('./1')
console.log(m) // { a: 1, b: 2 }
this.a = 1
this.b = 2 // 等同于 exports.b = 2 或者 module.exports.b = 2
// 或者也可以直接 将 a, b 都放入对象中 统一 module.exports = {a: 1, b: 2}
es module
// 静态依赖
import a from './a.js'
// 动态依赖
import('./a.js').then(m => {
console.log(m) // m 就是 ./a.js 导出的模块
})
export default 'hello world' // 默认导出
export const a = 123 // 具名导出
符号绑定:
区别
- CMJ 是社区标准,ESM 是官方标准
- CMJ 是使用API实现的模块化,ESM 是使用新语法实现的模块化
- CMJ 仅在node环境中支持,ESM 各种环境均支持
- CMJ 是动态的依赖,同步执行。ESM 既支持动态,也支持静态(只能写在模块的最顶部,在代码运行前就要确定依赖关系),动态依赖是异步执行的。
- ESM 导入时有符号绑定(直接导入引用,所以对引用进行操作,原模块也会跟着改变),CMJ 只是普通函数调用和赋值