Appearance
模块化系统
什么是模块化系统
模块化系统是一种将代码组织成独立、可重用单元的方法。在 Node.js 中,模块化系统允许开发者将代码分割成多个文件,每个文件负责特定的功能,然后通过导入/导出机制在不同文件之间共享代码。
Node.js 模块化系统的历史
1. CommonJS 模块系统
- Node.js 最初采用的模块系统
- 使用
require()导入模块 - 使用
module.exports导出模块 - 同步加载模块
2. ES 模块系统
- ECMAScript 2015 (ES6) 引入的模块系统
- 使用
import导入模块 - 使用
export导出模块 - 异步加载模块
- Node.js v12+ 支持
CommonJS 模块系统
导出模块
javascript
// 导出单个值
module.exports = value;
// 导出多个值
module.exports = {
value1,
value2,
value3
};
// 或
exports.value1 = value1;
exports.value2 = value2;
exports.value3 = value3;导入模块
javascript
// 导入整个模块
const module = require('./module');
// 导入特定值
const { value1, value2 } = require('./module');
// 导入内置模块
const fs = require('fs');
// 导入第三方模块
const express = require('express');模块解析规则
- 如果模块路径以
.或..开头,则解析为相对路径 - 如果模块路径是一个文件名,则解析为该文件
- 如果模块路径是一个目录,则尝试加载该目录下的
index.js文件 - 如果以上都失败,则在
node_modules目录中查找
ES 模块系统
导出模块
javascript
// 导出单个值
export default value;
// 导出多个值
export const value1 = 'value1';
export const value2 = 'value2';
// 或
export {
value1,
value2
};导入模块
javascript
// 导入默认值
import value from './module.js';
// 导入特定值
import { value1, value2 } from './module.js';
// 导入所有值
import * as module from './module.js';
// 导入内置模块
import fs from 'fs';
// 导入第三方模块
import express from 'express';启用 ES 模块
- 将文件扩展名改为
.mjs - 在
package.json中设置"type": "module"
模块的缓存
- Node.js 会缓存已加载的模块
- 多次
require同一个模块只会执行一次 - 缓存可以提高性能
- 但也可能导致状态共享的问题
模块的循环依赖
- 当模块 A 依赖模块 B,模块 B 又依赖模块 A 时,会产生循环依赖
- CommonJS 模块系统会返回未完成的模块导出
- ES 模块系统会返回模块的引用
最佳实践
1. 模块设计
- 每个模块只负责一个特定的功能
- 模块大小适中,避免过大或过小
- 清晰的模块接口
2. 目录结构
- 按功能组织模块
- 合理的文件夹结构
- 统一的命名规范
3. 依赖管理
- 明确的依赖关系
- 避免循环依赖
- 合理使用第三方模块
4. 代码风格
- 一致的代码风格
- 清晰的注释
- 模块化的命名规范
工具和库
1. 模块 bundler
- Webpack
- Rollup
- Parcel
2. 模块加载器
- requireJS
- SystemJS
3. 包管理器
- npm
- Yarn
- pnpm
实践练习
- 创建一个使用 CommonJS 模块系统的项目
- 创建一个使用 ES 模块系统的项目
- 实现模块之间的依赖关系
- 处理模块的循环依赖