ES Module和CommonJS Moudle是什么?
ES Module和CommonJs都是一种Javascript的模块规范,一些不同的库遵循了不同的模范,如vue遵循ES Module规范,express遵循CommonJS规范。
ES Module和CommonJS导入和导出有什么区别
nodejs支持ES Module和CommonJs模块。当遇到.mjs时会按照ES Module规范去解析文件,遇到.cjs文件时会按照CommonJs规范来解析文件。下面我们通过nodejs来看看ES Module和Common Js规范导出和引入的区别。
CommonJS
CommonJS导出
Commonjs使用module.exports或exports进行导出,其中exports为module.exports的引用。如
// a.cjs
module.exports = {
content: 'I am a Obj from acjs'
}
或者
// a.cjs
exports.content = "I am a Obj from acjs"
使用exports不可以直接指定对象
因为exports是module.exports的引用,将其指向新对象后,其就失去了联系,如下面代码会被忽视
// a.cjs
exports = {
content: 'I am a Obj from acjs'
}
当我们在其他地方引入a.cjs的时候会得到一个空对象,如
// b.cjs
let aObj = require('./a.cjs');
console.log(aObj); // {}
CommonJs导入
如上例子,CommonJs使用reuqire()方法来实现导入并接收对象。
ES Module
ES Module导出
ES Module导出使用export关键字,一个模块允许有多个"命名导出",但只允许有一个默认导出。其中命名导出指的是export后直接跟函数或者变量的定义。export default为默认导出。如
// c.mjs
export const c = 'I am a const',d='I am a const,too';
export function aFun(){
console.log('I am a fun');
}
export default { content: 'I am a default export'}
ES Module导入
ES Module使用import关键字进行导入,其规则如下
- 导入由export导出的对象时,语法为import { xxx } from "路径"
- 导入由export default导出的对象时,可以去掉花括号,如import xxx from "路径",此处的xxx为自定义名称
- import {xxx} from "路径"也可以使用as关键字来自定义名称,如 import {aaa as bbb} from "路径"
import c, { anotherObj , aFun as cFun} from './c.mjs'
console.log(c);
console.log(anotherObj);
console.log(cFun)
关于CommonJs和ESModule多次导出以及导出是否为同一对象问题
我的实践结果为,多次导入同一.cjs或者.mjs文件,对应的文件代码都只执行一次,并且导出的为对象的引用。和网上的说法有些出入。下面贴出实验截图,如有错误,烦请指出
cjs
可以看到b.cjs和main.cjs都引入了a.cjs,但a.cjs中的代码只被运行了一次,且关于对象类型,导出的为对象类型的引用。
mjs
mjs情况类似