◆

JavaScript 模块化:ES6 与 CommonJS 差异对比

2023-02-02 01:370

模块

在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。 ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。


ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。 CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

CommonJS/ES6 示例

下面代码的实质是整体加载 fs 模块(即加载 fs 的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 3 个方法。 这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。

let { stat, exists, readfile } = require('fs');

// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;

ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,再通过 import 命令输入。 下面代码的实质是从 fs 模块加载 3 个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载, 即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。

// ES6模块
import { stat, exists, readFile } from 'fs';

JavaScript 现在有两种模块。一种是 ES6 模块,简称 ESM;另一种是 CommonJS 模块,简称 CJS。

  • CommonJS 模块使用 require() 和 module.exports,ES6 模块使用 import 和 export。

ES6 模块与 CommonJS 模块的差异

  • CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
  • CommonJS 模块的 require() 是同步加载模块,ES6 模块的 import 命令是异步加载,有一个独立的模块依赖的解析阶段。
  • CommonJS 加载的是一个对象(即 module.exports 属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成

本文参考链接:参考链接

💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEJavaScript 模块化:ES6 与 CommonJS 差异对比加载中