Skip to content

ESModule 与 CommonJS

CommonJS

使用方式:

js
const add = function (x, y) {
  return x + y
}

module.exports.add = add
js
const add = require('./add.js')
console.log(add.add(1, 1))

ESModule

使用方式:

js
const add = function (x, y) {
  return x + y
}

export { add }
// export default add
js
import { add } from './add.js'
// import add from './add.js'
console.log(add.add(1, 1))

两者区别

  • CommonJS 是对模块的浅拷贝,ES6 Module 是对模块的引用,即 ES6 Module 只存只读,不能改变其值,具体点就是指针指向不 能变,类似 const, import 的接口是 read-only(只读状态),不能修改其变量值。 即不能修改其变量的指针指向,但可以改 变变量内部指针指向, 可以对 commonJS 对重新赋值(改变指针指向),但是对 ES6 Module 赋值会编译报错。

  • CommonJS 模块是运行时加载,ES6 Module 模块是编译时输出接口。

举个例子

js
// 输出模块 counter.js
let counter = 3
function incCounter() {
  counter++
}
module.exports = {
  counter: counter,
  incCounter: incCounter,
}
js
// 引入模块 main.js
const mod = require('./counter')

console.log(mod.counter) // 3
mod.incCounter()
console.log(mod.counter) // 3

对于基本类型的数据,它的内部变化就影响不到输出的 mod.counter 了

但是对于引用类型:

js
// 输出模块 counter.js
const counter = {
  value: 3,
}

function incCounter() {
  counter.value++
}
module.exports = {
  counter: counter,
  incCounter: incCounter,
}
js
// 引入模块 main.js
const mod = require('./counter.js')

console.log(mod.counter.value) // 3
mod.incCounter()
console.log(mod.counter.value) // 4

value 是会发生改变的。

对于 ES6 Module

js
// counter.js
export let counter = 3
export function incCounter() {
  counter++
}

// main.js
import { counter, incCounter } from './counter'
console.log(counter) // 3
incCounter()
console.log(counter) // 4