CommonJS的产生
CommonJS 由 Mozilla 工程师 Kevin Dangoor 于 2009 年 1 月创立,最初命名为ServerJS。2009 年 8 月,该项目更名为CommonJS。旨在解决 Javascript 中缺少模块化标准的问题。
Node.js 后来也采用了 CommonJS 的模块规范。
module与require
在CommonJS中,module与require并非js关键字,而是一个对象与函数,这可以去打印看看
js
console.log(module)
{
id: '.',
path: '/Users/xx/code/test-code',
exports: {},
filename: '/Users/xx/code/test-code/s.cjs',
loaded: false,
children: [],
paths: [
'/Users/xx/code/test-code/node_modules',
'/Users/xx/code/node_modules',
'/Users/xx/node_modules',
'/Users/node_modules',
'/node_modules'
]
}
console.log(require)
[Function: require] {
resolve: [Function: resolve] { paths: [Function: paths] },
main: {
id: '.',
path: '/Users/xx/code/test-code',
exports: {},
filename: '/Users/xx/code/test-code/s.cjs',
loaded: false,
children: [],
paths: [
'/Users/zhutao/code/test-code/node_modules',
'/Users/zhutao/code/node_modules',
'/Users/zhutao/node_modules',
'/Users/node_modules',
'/node_modules'
]
},
extensions: [Object: null prototype] {
'.js': [Function (anonymous)],
'.json': [Function (anonymous)],
'.node': [Function (anonymous)]
},
cache: [Object: null prototype] {
'/Users/xx/code/test-code/s.cjs': {
id: '.',
path: '/Users/xx/code/test-code',
exports: {},
filename: '/Users/xx/code/test-code/s.cjs',
loaded: false,
children: [],
paths: [Array]
}
}
}
我们可以看到两个对象,其中的module.exports是module下面的一个对象 exports只是module.exports下面的引用
所以当module.exports与exports同时存在时,只会导出module.exports
js
//s.cjs
module.exports = {
name: 1,
};
exports = {
age: 1,
};
//或者
exports = {
age: 1,
};
module.exports = {
name: 1,
};
//a.cjs
const modu = require("./s.cjs");
console.log(modu); //{ name: 1 }
同样,exports改变指针指向也会导致导出失效,
所以exports只能以exports.xx = xx;的方式导出
js
// s.cjs
exports = {
age: 1,
};
//a.cjs
const modu = require("./s.cjs");
console.log(modu); //{}
// s.cjs
exports.name = {
age: 1,
};
//a.cjs
const modu = require("./s.cjs");
console.log(modu); //{ name: { age: 1 } }
但使用exports.xx =xx;后上下文都有module.exports = {} 讲改变指针指向,原本的exports将失去导出效果
language
//只有module.exports生效 既然导出对象只有name没有age
module.exports = {
name: 1,
};
exports.age = 12;
ESM
在ESM中import与export 与export default 是一对关键字
并且ESM模块解析是发生在编译阶段,而CommonJS是发生在运行阶段,这个很好理解,CommonJS本身就是函数,既然是函数就要运行时进行解析。
区别
- 二者最外层this指向不一样,Common.js指向exports ESM指向undefined。
最外层this也能导出,但遇到使用module.exports改变指向时会失去效果 2. ESM没有__dirname与__filename