引入模块
在 Node.js 中,CommonJS 是一种用于定义模块的标准。引入一个模块通常使用 require 函数来完成。例如,如果你想引入 fs 模块,可以这样写:
const fs = require('fs');这个过程实际上会创建一个模块上下文,然后执行该模块的代码,最后返回一个对象。这个对象包含了该模块对外暴露的内容。
导出模块
为了导出模块中的变量、函数或对象,你可以使用 module.exports 或 exports 对象。它们都可以用来导出模块内容,但需要注意的是,exports 实际上是 module.exports 的一个引用。
使用 module.exports 导出
module.exports 可以直接赋值为任何 JavaScript 类型的对象,包括函数、数组、字符串等。例如:
// myModule.js
module.exports = {
name: 'My Module',
version: '1.0.0'
};使用 exports 导出
exports 是 module.exports 的一个引用,因此可以直接通过它来添加属性和方法。例如:
// myModule.js
exports.name = 'My Module';
exports.version = '1.0.0';
exports.logInfo = function() {
console.log(`Module Name: ${this.name}, Version: ${this.version}`);
};使用 exports 和 module.exports 的区别
虽然 exports 可以方便地添加属性和方法,但如果需要将整个模块导出为一个特定的对象,则必须直接使用 module.exports。例如:
// www.javascriptcn.com code example
// myModule.js
exports.name = 'My Module'; // 通过 exports 添加属性
exports.version = '1.0.0';
// 如果需要替换整个导出内容,必须使用 module.exports
module.exports = {
logInfo: function() {
console.log(`Module Name: ${this.name}, Version: ${this.version}`);
}
};模块作用域
每个模块都有自己的作用域,这意味着模块内部定义的变量和函数不会污染全局作用域。例如,在模块中定义的变量和函数不会在其他模块或全局环境中被访问到。
模块内部的变量和函数
假设你在模块中定义了一个变量和一个函数:
// myModule.js
let secret = 'This is a secret!';
function getSecret() {
return secret;
}
module.exports.getSecret = getSecret;在这个例子中,外部无法直接访问 secret 变量,只能通过 getSecret 函数获取其值。
模块缓存机制
Node.js 会对已经加载过的模块进行缓存,这意味着如果多次使用 require 加载同一个模块,Node.js 会返回缓存中的实例,而不是重新加载模块代码。这有助于提高性能,但需要注意,这也意味着修改了模块文件后,需要重启 Node.js 应用才能使更改生效。
如何强制重新加载模块
如果你确实需要重新加载模块,可以使用 delete require.cache[require.resolve('./myModule')] 来删除缓存,从而迫使 Node.js 重新加载模块。
delete require.cache[require.resolve('./myModule')];
const myModule = require('./myModule');这样就可以确保每次加载时都得到最新的模块内容。
模块路径解析
当使用 require 加载模块时,Node.js 会按照一定的规则来解析模块路径。默认情况下,Node.js 会首先尝试在当前目录下寻找指定的模块。如果找不到,则会继续搜索父目录,直到找到模块或到达文件系统的根目录为止。
绝对路径和相对路径
- 绝对路径:从文件系统的根目录开始的路径。
- 相对路径:相对于当前模块文件的位置。
使用 node_modules 目录
Node.js 还会在 node_modules 目录中查找模块。当你安装第三方库时,这些库通常会被安装到项目根目录下的 node_modules 文件夹中。通过这种方式,可以很容易地在项目中使用这些库。
示例
假设你的项目结构如下:
/project-root
/node_modules
/lib
myModule.js
app.js在 app.js 中引入 myModule.js 可以这样做:
const myModule = require('./lib/myModule');这样,Node.js 会先在当前目录(app.js 所在目录)的 lib 子目录中查找 myModule.js。
总结
本章介绍了 Node.js 中如何使用 CommonJS 规范来管理模块。通过了解如何引入、导出模块,以及模块的作用域、缓存机制和路径解析,你可以更好地组织和维护你的代码。接下来的章节将进一步深入讨论 Node.js 的其他核心概念和高级功能。