ES6 中的模块化
CommonJS 规范
什么是 CommonJS
CommonJS
是JS
社区在 2009 年提出的一系列标准的统称,其中包含了模块、文件、IO、控制台等标准。Node.js
的实现中采用了CommonJS
标准的一部分,并对它进行了一些调整。我们日常工作中所说的CommonJS
实际上是指Node.js
中实现的版本,不是它的原始定义。CommonJS
中规定每个文件是一个模块。
CommonJS 导入导出
模块导出 使用
module.exports
或exports
对象将模块中的内容导出,以便其他模块可以使用。js// math.js function add(a, b) { return a + b; } module.exports = add;
模块导入 使用
require
函数导入其他模块。js// app.js const add = require("./math"); const result = add(2, 3); console.log(result); // 输出 5
CommonJS 特点
CommonJS
规范加载模块是同步的,只有加载完成,才能执行后面的操作。
CommonJS
规范中,模块化是通过module
、exports
和require
这三个核心概念来实现的:每个文件就是一个模块,有自己的作用域。每个模块内部,
module
变量代表当前模块,是一个对象,它的exports
属性(即module.exports
)是对外的接口。module.exports
属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.exports
变量。require
函数用于导入其他模块。它接受一个模块的路径或名称,并返回该模块导出的内容。
ES6 module 规范
ES6
模块(也称为ECMAScript
模块或ES
模块)是JavaScript
的一种标准化模块系统,旨在解决CommonJS
和AMD
模块系统的一些问题。ES6
模块在浏览器和服务器端环境(如Node.js
)中都可以使用。
ES6 module 导入导出
模块导出 使用
export
关键字将模块中的内容导出js// math.js export function add(a, b) { return a + b; }
模块导入 使用
import
关键字导入其他模块js// app.js import { add } from "./math.js"; const result = add(2, 3); console.log(result); // 输出 5
ES6 模块的特点
- 静态分析:
ES6
模块在编译时就能确定模块的依赖关系,有助于进行静态分析和优化。 - 异步加载:
ES6
模块支持异步加载,适合在浏览器环境中使用。 - 标准化:
ES6
模块是JavaScript
的标准模块系统,得到广泛支持。 - 兼容性:旧版浏览器和
Node.js
需要使用工具(如 Babel)进行转译或配置(如使用 --experimental-modules 标志)才能支持 ES6 模块。
ES6 module 和 CommonJS module 的区别
CommonJS
的require
语法是同步的,导致CommonJS
模块规范只适合用在服务端,而ES6
模块无论是在浏览器端还是服务端都是可以使用的,但是在服务端中,还需要遵循一些特殊的规则才能使用(使用.mjs
扩展名、设置"type": "module"
等等)CommonJS
模块输出的是一个值的拷贝,而ES6
模块输出的是值的引用(意思是,CommonJS
一旦输出一个值,模块内部的变化不会影响到这个值;ES6
原始值变了import
加载的值也会跟着变化)CommonJS
模块是运行时加载,而ES6
模块是编译时输出接口,使得对JS
的模块进行静态分析成为了可能模块顶层的
this
指向,在CommonJS
顶层,this
指向当前模块;而在ES6
模块中,this 指向 undefined关于两个模块互相引用的问题,在
ES6
模块当中,支持加载CommonJS
模块的。但是反过来,CommonJS
并不能require ES6
模块,在NodeJS
中,两种模块方案是分开处理的
ES6 module、CommonJS module 循环引用的问题
循环加载指的是 a 脚本的执行依赖 b 脚本,b 脚本的执行依赖 a 脚本
CommonJS
模块是加载时执行。一旦出现某个模块被“循环加载”,就只输出已经执行的部分,没有执行的部分不会输出。ES6
模块对导出模块,变量,对象是动态引用,遇到模块加载命令import
时不会去执行模块,只是生成一个指向被加载模块的引用,保证真正取值时能够取到值,只要引用是存在的,代码就能执行。