CommonJS 和 ES6 模块引入的区别
CommonJS 和 ES6 模块系统在语法、加载方式和导出机制上的差异
问题
CommonJS 和 ES6 中模块引入有什么区别?
解答
CommonJS
CommonJS 主要用于 Node.js 环境,使用 require 引入模块,module.exports 导出模块。
导出模块:
// moduleA.js
const name = 'John';
module.exports = name;
// 或者导出一个对象
const person = { name: 'John', age: 30 };
module.exports = person;
引入模块:
// main.js
const name = require('./moduleA');
console.log(name); // 'John'
const person = require('./moduleA');
console.log(person.name); // 'John'
特点:
- 动态引入:
require可以在函数体内、条件语句中使用
if (condition) {
const moduleA = require('./moduleA');
}
-
同步加载:模块在执行
require时立即加载并返回结果 -
导出值的拷贝:对于引用类型,修改属性会在所有引用中反映
const obj = require('./moduleA');
obj.newProp = 'new';
console.log(require('./moduleA').newProp); // 'new'
ES6 模块
ES6 模块是 ECMAScript 标准的一部分,使用 import 和 export 语法。
导出模块:
// moduleA.js
export const name = 'John';
// 导出默认值
const person = { name: 'John', age: 30 };
export default person;
引入模块:
// main.js
import { name } from './moduleA';
console.log(name); // 'John'
// 引入默认导出
import person from './moduleA';
console.log(person.name); // 'John'
特点:
- 静态引入:
import必须在文件顶部声明,不能在函数体或条件语句中使用
// 错误的用法
if (condition) {
import { name } from './moduleA'; // 报错
}
-
异步加载:浏览器中的 ES6 模块是异步加载的,不会阻塞页面
-
导出值的引用:导出模块中的值变化时,所有引用都会同步更新
// moduleA.js
export let count = 1;
setTimeout(() => { count += 1; }, 1000);
// main.js
import { count } from './moduleA';
setTimeout(() => { console.log(count); }, 2000); // 2
兼容性
在 Node.js 环境中,可以使用 Babel 或 Webpack 将 ES6 模块转换为 CommonJS 模块。现代构建工具支持同时使用两种模块系统,并在构建时根据目标环境转换。
关键点
- 语法:CommonJS 使用
require/module.exports,ES6 使用import/export - 加载方式:CommonJS 是同步加载,ES6 是静态分析和异步加载
- 导出机制:CommonJS 导出值的拷贝,ES6 导出值的引用
- 使用场景:CommonJS 主要用于 Node.js,ES6 模块是标准规范,适合现代前端开发
- 动态性:CommonJS 支持动态引入,ES6 模块必须静态声明
目录