【study】Es Module 和 CommonJs的区别

148 阅读3分钟
1、Es Module 和 CommonJs
  • ES Modules(ESM)和 CommonJS 是 JavaScript 中两种主要的模块化系统。它们在使用方式、加载机制和语法上存在一些显著的差异
2、语法与使用方式
  • ES Modules (ESM)
// 导出

// Named export
export const name = 'Alice';
export function greet() {
  console.log('Hello');
}

// Default export
const age = 30;
export default age;

// 导入

// Named import
import { name, greet } from './module.js';

// Default import
import age from './module.js';

// Import everything
import * as module from './module.js';

  • CommonJS
// 导出

// Named export
const name = 'Alice';
function greet() {
  console.log('Hello');
}

module.exports = {
  name,
  greet
};

// Default export
module.exports = age;

// 导入

// Named import
const { name, greet } = require('./module.js');

// Default import
const age = require('./module.js');

3、加载机制
  • ES Modules
// 静态加载:ESM 在编译阶段就会解析和确定模块的依赖关系,这是所谓的“静态导入”。
//         这意味着在代码执行之前,模块依赖项已经被解析,有助于实现更好的优化和更高的性能。


//  异步加载:在浏览器中,ESM 的加载是异步的,因此可以利用 `import()` 得到动态导入。

import('./module.js').then(module => {
  console.log(module);
});

  • CommonJS
// 动态加载:CommonJS 使用动态加载,即在运行时同步解析和加载模块。每次 `require` 调用都会读取并执行模块逻辑。
- 同步加载:在 Node.js 中,`require` 是同步的,这在处理文件系统时可能会导致阻塞。
4、模块作用域与缓存
  • ES Modules
// 模块作用域:每个 ES 模块都有自己的作用域。顶层的 `this` 在模块中是 `undefined`

// In ESM, top-level 'this' is undefined
console.log(this); // undefined

// 模块缓存:ESM 遵循单一实例原则,模块加载后会被缓存。后续的导入会引用同一个实例。
  • CommonJS
// 模块作用域:CommonJS 模块也有自己的作用域,但顶层的 `this` 指向 `module.exports`。

// In CommonJS, top-level 'this' is 'exports'
console.log(this); // module.exports

// 模块缓存:CommonJS 也会缓存已加载的模块来提升性能,避免重复加载
5、运行时环境支持
  • ES Modules
// 浏览器:原生支持 `<script type="module"></script>`,支持 ECMA Script 6 及以上版本。

<script type="module" src="main.js"></script>


// Node.js:从 Node.js 13.x 版本开始,已稳定支持 ES Modules,但需要模块文件添加 `.mjs` 拓展名,或在 `package.json` 中指定 `"type": "module"`。

{
  "type": "module"
}

  • CommonJS
// 浏览器:不原生支持,需要使用打包工具(如 Webpack、Browserify)将 CommonJS 模块转换为浏览器可用的格式。

// Node.js:原生支持,Node.js 默认使用 CommonJS 模块系统。
6、结论
  • 语法简洁性:ES Modules 的静态导入和简洁的语法使得模块化更加直观。
  • 加载机制:ES Modules 的静态加载提供了更好的优化机会,而 CommonJS 的动态加载具有更大的灵活性。
  • 环境:对浏览器原生支持和现代化开发工具链的适应性,让 ES Modules 更适合现代 Web 开发;CommonJS 则由于其在 Node.js 环境中的广泛应用而依然占据重要地位。
7、vue中的使用
  • ES Modules:Vue.js 鼓励使用 ES Modules,尤其是在浏览器环境和现代工具链中。ES Modules 语法简洁、优化性能好,适用于大多数前端开发场景。
  • CommonJS:Vue.js 也兼容 CommonJS,特别是在 Node.js 环境中工作时。一些工具和插件可能会使用 CommonJS 语法,但是大多数前端代码是使用 ES Modules 编写的。