本文是JavaScript模块系统系列的第二篇。
CommonJS
CommonJS旨在为服务端JavaScript应用程序的模块化开发提供规范。在NodeJS最初的几个版本中,开发人员也是需要遵守CommonJS规范,由于各种原因NodeJS最终形成了自己的一套模块系统实现,但仍然无法脱离CommonJS规范的影响:
// In circle.js
const PI = Math.PI;
exports.area = (r) => PI * r * r;
exports.circumference = (r) => 2 * PI * r;
// In some file
const circle = require('./circle.js');
console.log( `The area of a circle of radius 4 is ${circle.area(4)}`);
无论是CommonJS规范还是NodeJS,都会涉及两个基本接口的调用,即require和exports。require接受模块ID,将其它模块导入到当前作用域供后续调用,NodeJS模块通常存放在node_modules文件夹下。
exports用于暴露公共接口供require导入,与CommonJS规范不同的是,NodeJS的具体实现是module.exports,也有exports变量,但本质上是对module.exports的引用。如果将整个对象赋值给exports,将破坏exports对module.exports的绑定:
// This won't work, replacing exports entirely breaks the binding to
// modules.exports.
exports = (width) => {
return {
area: () => width * width
};
}
// This works as expected.
module.exports = (width) => {
return {
area: () => width * width
};
}
由于CommonJS从一开始就是为服务端开发服务的,只考虑同步化调用,且按照require在文件中的调用位置进行顺序加载模块,所以不适合Web客户端。
特点
- 使用简单;
- 支持依赖管理;
- 可随时调用require导入模块;
- 解决了模块间的循环依赖问题。
缺点
- 同步化方案不适合Web客户端;
- 浏览器原生不支持,需要添加额外的库;
- 不适合对源码进行静态分析。
推荐文章