当前位置: 首页>大数据>正文

ESM vs CJS

学自:https://webreflection.medium.com/cjs-vs-esm-5f8b90a4511a

安全性

ESM 较 CJS 更加安全。

// module.js
export let a = 'a';
export let b = 'b';
export let c = 'c';
// index.js
import * as esmModule from './module.js';
esmModule.a = 'z';
console.log(esmModule);
// result:
esmModule.a = 'z';
            ^
TypeError: Cannot assign to read only property 'a' of object '[object Module]'

作为对比,CJS 可以修改 modules.export 中的值。

测试

CJS 相较于 ESM 更容易测试。

  • CJS 支持 缓存无效
  • 分析工具可以挂载在任何模块上
  • 代码执行时,可以分析第三方组件的指标和变化
require('module');
// some stuff
// module cache invalidation
delete require.cache[require.resolve('module')];
// some other stuff
require('module');

Treeshaking

ECMAScript 可以支持 Treeshaking,CommonJS 不行。ECMAScript 现实中也没能从 Treeshaking 中获利。因为浏览器需要下载对应的资源(node 需要阅读对应的代码)才能知道如何 Treeshaking。事实上,应该只有 AOT (Ahead of Time) 编译器可以从 Treeshaking 获利。

幸运的是,在语法分析阶段(parsing phase),执行引擎可以知道哪些代码需要处理和优化,哪些不能。但是这引起了一些误解。

  • CJS 和 ESM 都支持动态引入代码,动态引入代码事实上打败了 treeshaking 的优势。
async function loadMyModule() {
  const { 
    default: defaultImport,
    namedExport1,
    namedExport2
  } = await import('./mixedExportModule.js');
  // ...
}
loadMyModule();
  • CJS / ESM 都支持对某些模块有特定的 export 路径。例如,lo-dash 可以把所有的模块在一个文件中 export,也可以用单独的文件 export 每个模块。

可见 CJS / ESM 在 Treeshaking 方面可能都不是赢家。如果一个模块从 Treeshaking 中获利很多,可能有更好的方案,把这个模块切分成多个模块或者可以单独引入的子模块。

live binding + default

ESM 支持 live binding,而 CommonJS 不支持。

ESM 在 export 变量时,是以引用的方式被引入的。这与 CommonJS 的方式有所不同。当模块内的变量值有所变动时,引入方再读取变量值时可以获得新的值。

MIME 类型

只要 HTTP 中相关的 header mime 类型是对的,ESM 不关心文件后缀名。例如 .js 在 NodeJS 世界上是一个 CJS 类型文件。 在Web 中 .gif 的文件,也可以用 application/javascript 类型返回。

结论

谈论一下技术细节可能比简单说 ESM 和 CJS 哪个更好有意义。


https://www.xamrdz.com/bigdata/75y1996396.html

相关文章: