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时不会去执行模块,只是生成一个指向被加载模块的引用,保证真正取值时能够取到值,只要引用是存在的,代码就能执行。
