它们有三个重大差异。
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
- CommonJS 模块的
require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段。
遵循的规范不一样
- require/exports 是CommonJS的一部分
- import/export 是ES6规范
出现时间不同
CommonJS 作为Node.js的规范,一直沿用至今。npm上使用CommonJS的库众多,因此node无法至今兼容ES6。所以现阶段,require/exports仍然是必要的。
书写方式不同
require/exports 用法:
const fs = require('fs');
-------------------------
exports.fs = fs;
module.exports = fs;
import/export 写法多样:
mport fs from 'fs';
import {default as fs} from 'fs';
import * as fs from 'fs';
-----------------------------
export default fs;
export const fs;
export * from 'fs';
本质上不同
- 1:无论CommonJS还是ES6 Module 输出都可以看成是一个具备多个属性或者方法的对象;
- 2: CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用,CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值
针对对上面第二条,代码示例:
// counter.js
exports.count = 0
setTimeout(function () {
console.log('increase count to', ++exports.count, 'in counter.js after 500ms')
}, 500)
// commonjs.js
const {count} = require('./counter')
setTimeout(function () {
console.log('read count after 1000ms in commonjs is', count)
}, 1000)
//es6.js
import {count} from './counter'
setTimeout(function () {
console.log('read count after 1000ms in es6 is', count)
}, 1000)
运行结果:
➜ test node commonjs.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in commonjs is 0
➜ test babel-node es6.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in es6 is 1
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
import静态编译,import的地址不能通过计算
require就可以,例如 const url = "a" + "b";
Import url 直接报错了
require(url)不会报错
所以require都会用在动态加载的时候