【工程化】CJS 和 ESM

65 阅读1分钟

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 // 具名导出

符号绑定:

image.png

image.png

区别

  1. CMJ 是社区标准,ESM 是官方标准
  2. CMJ 是使用API实现的模块化,ESM 是使用新语法实现的模块化
  3. CMJ 仅在node环境中支持,ESM 各种环境均支持
  4. CMJ 是动态的依赖,同步执行。ESM 既支持动态,也支持静态(只能写在模块的最顶部,在代码运行前就要确定依赖关系),动态依赖是异步执行的。
  5. ESM 导入时有符号绑定(直接导入引用,所以对引用进行操作,原模块也会跟着改变),CMJ 只是普通函数调用和赋值