1. 什么是模块?
在 Node.js 中,模块是功能代码的封装单元,模块化帮助开发者将大项目拆解成多个独立的小模块,每个模块可以提供一组特定的功能。 Node.js 支持以下几种模块:
- 内置模块:Node.js 自带的模块,如
fs
、http
、path
等。 - 用户自定义模块:由开发者创建的模块。
- 第三方模块:通过 npm 安装的模块,如
express
、lodash
等。
2. 内置模块
Node.js 自带了许多内置模块,开发者可以直接使用它们,无需额外安装。常见的内置模块包括:
- http:用于创建 HTTP 服务器和客户端。
- fs:用于文件系统操作,如读写文件。
- path:用于处理文件路径。
- os:提供操作系统相关的信息。
- events:用于事件驱动编程。
例如,使用 http
模块创建一个简单的服务器:
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, Node.js!');
});
server.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
3. 用户自定义模块
除了内置模块,Node.js 还允许开发者创建自定义模块。每个模块都是一个单独的文件,可以导出需要共享的函数、对象或变量。
创建一个自定义模块 math.js
:
// math.js
exports.add = (a, b) => a + b;
exports.subtract = (a, b) => a - b;
在另一个文件中引入并使用该模块:
// app.js
const math = require('./math');
console.log(math.add(5, 3)); // 输出: 8
console.log(math.subtract(5, 3)); // 输出: 2
4. require
与模块加载
require
是 Node.js 加载模块的机制。它不仅支持加载内置模块,还支持加载本地文件模块和第三方模块。加载的过程是同步的,Node.js 会缓存已经加载的模块,以提高性能。
- 加载内置模块时直接使用模块名,如
require('http')
。 - 加载本地模块时,路径是必需的,比如
require('./math')
。 - 第三方模块需要先通过
npm install
安装。
5. 模块的作用域
每个模块都有自己的作用域。模块内的变量和函数默认是私有的,不能被外部访问。通过 exports
或 module.exports
对外暴露接口,供其他模块使用。
// foo.js
const secret = 'I am secret';
exports.reveal = () => secret;
// bar.js
const foo = require('./foo');
console.log(foo.reveal()); // 输出: I am secret
6. 模块缓存
Node.js 会缓存已经加载的模块。如果你多次 require
同一个模块,Node.js 会返回缓存中的模块,而不是重新加载它。这有助于提高性能,避免重复计算和资源浪费。
7. 模块的导入与导出方式
7.1、导出模块: 使用 module.exports 或 exports 将函数、对象或变量导出。
7.2、导入模块: 使用 require() 导入模块。
module.exports
:最直接的方式,完全替代exports
,可以导出一个单一的对象或函数。
// math.js
module.exports = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
};
// app.js
const math = require('./math');
console.log(math.add(2, 3)); // 输出: 5
exports
:通过exports
对象添加多个接口,但需要注意不能直接赋值给exports
,否则会失去原有的引用。
// math.js
exports.add = (a, b) => a + b;