CommonJs 和 ES Module

154 阅读3分钟

CommonJs 和 ES Module

CommonJs

1. 导出:

module.exports = {
	name : "小明"
}
module.exports.name = "小明"

exports.name = "名字"
exports.sex = "male"

可以使用module.exports 导出,也可以只使用exports 导出,不同的是,使用多个exports导出时,只有最后一个导出会生效,上面的例子中只有sex导出成功。

2.导入

// index.js
module.exports.name = "小明"

let data = require("./index.js")
console.log(data) // { name: "小明" }

可以使用require来获取

动态导入

CommonJs支持动态导入

let list = ["./index.js", "./config.js"]
list.forEach((url) => require(url))
导入值的变化
// index.js
let num = 0;
module.exports = {
    num,
    add() {
		++ num
    },
    numValue() {
        console.log(num)
    }
}

let { num, add,numValue } = require('./index.js')
console.log(num) // 0
add()
console.log(num) // 0
numValue() // 1
num = 10
console.log(num) // 10

在上述例子中可以看到,在调用add()方法之后,num的值并没有被改变,但是在调用numValue的时候发现num改变了,说明此时改变的是index.js中的num,接着我们对num进行赋值,num的值变成了10。

因此可以说明,通过CommonJs导入的基本变量是深拷贝的,复杂类型是属于浅拷贝

ES Module

1.导出

// 变量导出
export const name = "小明"

// 函数导出
export function fn1 () {}
export const fn2 = () => {}

// 多个一起导出
const name = "小明"
const sex = "male"
export {name, sex} 

// 默认导出
export default = {
    fn3() {},
    msg: "Hello ES Module"
}

在ES Module中分为单个导出默认导出,并且默认导出的优先级比单个导出要高,也就是说,当两种方法在导入的时候同时使用,需要先导入默认输出。

2. 导入

// index.js
export const name = "小明"
export const sex = "male"

import { name, sex } from "./index.js"
console.log(name, sex) // "小明", "male"

使用 import 语法导入,并且单个导入需要使用花括号 { }

导入值的变化
// index.js
export let num = 0;
export function add() {
    ++ num
}

import { num, add } from "./index.js"
console.log(num) // 0
add()
console.log(num) // 1
num = 10 // 抛出错误

在这里使用add()方法时,num的值发生了变化,在直接修改num的值的时候,发生了错误。说明ES Module导出的值是只读的

import的变量是只读的,不论是基本数据类型还是复杂数据类型。当模块遇到import命令时,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。

对于动态来说,原始值发生变化,import加载的值也会发生变化。不论是基本数据类型还是复杂数据类型。

静态

就是Es Module语句import只能声明在该文件的最顶部,不能动态加载语句,Es Module语句运行在代码编译时。

总结

CommonJS

  • 可以动态加载,代码发生在运行时
  • 导出的值是拷贝的,基本变量是深拷贝的,复杂类型是属于浅拷贝

ES Module

  • 不可以动态加载,属于静态,需要在文件最顶部声明,代码发生在编译时
  • 可以单个导出,也可以默认导出
  • 导出的值是只读的,不能修改

参考文章

聊聊什么是CommonJs和Es Module及它们的区别

CommonJS与ES6模块化规范区别,深拷贝与浅拷贝