CommonJS 模块是为 Node.js 打包 JavaScript 代码的原始方式。
使用 Browserify 可以将 CommonJS 风格的代码打包成浏览器可用的 JavaScript 文件。
模块文件
在 Node.js 中,每个文件都被视为一个单独的模块。
扩展名为 .cjs 的文件会被视为 CommonJS 模块。
Node.js 通过 package.json 中的 type 来判断 .js 文件是当作 ES6 模块文件 (module) 还是 CommonJS 模块文件 (commonjs)。
CommonJS 的工作原理
所有非 Node.js 原生模块(如 fs、path 等等)都是 Module 类的实例,它包含了该模块的一些信息。当使用一个模块时,会创建模块实例。
编写的模块代码最终是被放在一个函数内部执行的,每个模块都处于单独的函数作用域,所以不会造成污染全局变量的问题。
function wrap(exports, require, module, __filename, __dirname) {
// 模块代码
}
exports,等同于module.exports,作为module.exports的快捷访问;require,通常为模块原型上的require方法,用于加载其他模块;module,当前模块对象,通过new Module()实例化创建的;__filename,当前模块的绝对路径文件名;__dirname,当前模块所在目录的绝对路径。
在编写模块代码时,通过使用函数的参数,可以实现模块的导入和导出:通过 module.exports 实现了模块导出,可以将模块内部的某些代码共享给其他模块复用,通过 require 可以方便地加载其他模块的导出内容供当前模块使用。
此外,在非严格模式下,this 默认指向 module.exports,因此你可以直接在 this 上添加属性,这些属性会被添加到 module.exports 上。在严格模式下,this 是 undefined,因此不能直接在 this 上添加属性,否则会抛出错误。
导出模块的功能
模块导出的内容为 module.export,默认是一个对象 {},在 module.export 对象上增加属性即可导出模块的功能。
module.exports.age = 18;
module.exports.name = "My Name";
在初始时,exports 和 this (非严格模式) 均指向 module.exports,所以也可以使用下面的简写方法:
// 使用下面的简写(更常用)
exports.age = 18;
exports.name = "My Name";
// 或者
this.age = 18;
this.name = "My Name";
你也可以将任何你想导出的内容赋值给 module.exports,以将其作为模块的导出内容。
module.exports = foo;
module.exports = {
age: 18,
name: "My Name"
};
导入模块
使用 require() 函数导入其他模块。
// 内置模块
const fs = require('fs')
// 相对路径文件模块
const foo = require('./foo.js')
// 绝对路径文件模块
const absolutePathModule = require('/absolute/path/to/module')
// 第三方模块
const koa = require('koa')
参考
Node.js CommonJS 模块
https://nodejs.cn/api/modules.html