Skip to content

Webpack 核心功能实现

这是一个简化版的 Webpack 实现,展示了 Webpack 的核心功能。

项目结构

04-core-feature/
├── src/
│   ├── compiler.js         # 编译器
│   ├── compilation.js     # 编译对象
│   ├── module.js          # 模块
│   ├── parser.js          # 解析器
│   ├── chunk.js           # 代码块
│   └── loader.js          # 加载器
├── test/
│   ├── compiler.test.js
│   ├── compilation.test.js
│   ├── module.test.js
│   └── parser.test.js
├── package.json
└── README.md

核心功能

1. 编译器

Webpack 的核心,负责协调整个编译过程。

功能: 管理编译生命周期,执行插件,创建编译对象,监听模式。

2. 编译对象

单次编译的上下文,包含所有编译信息。

功能: 管理模块,管理代码块,管理资产,生成输出。

3. 模块

Webpack 的基本构建块。

功能: 解析依赖,应用加载器,计算大小,序列化。

4. 解析器

解析源代码,提取依赖关系。

功能: 解析 AST,提取 import/require,解析路径,依赖解析。

5. 代码块

模块的集合,最终输出为文件。

功能: 管理模块,计算大小,优化代码块,生成哈希。

6. 加载器

转换不同类型的文件。

功能: 加载器运行器,常用加载器,加载器上下文,异步处理。

使用方法

安装依赖

bash
npm install

运行测试

bash
npm test

启动编译器

bash
npm run dev

测试覆盖

所有核心功能都有对应的单元测试:

编译器测试,编译对象测试,模块测试,解析器测试。

实现细节

编译器

编译器使用 Tapable 实现钩子系统:

javascript
this.hooks = {
  run: new AsyncSeriesHook(['compiler']),
  compile: new SyncHook(['params']),
  compilation: new SyncHook(['compilation', 'params']),
  make: new AsyncSeriesHook(['compilation']),
  afterCompile: new AsyncSeriesHook(['compilation']),
  done: new AsyncSeriesHook(['stats']),
  failed: new SyncHook(['error'])
}

模块

模块使用 Acorn 解析 AST:

javascript
const ast = parse(source, {
  sourceType: 'module',
  ecmaVersion: 'latest',
  locations: true
})

加载器

加载器按顺序执行:

javascript
for (const loader of loaders) {
  result = await this.executeLoader(loader, result, filename)
}

与 Webpack 的对比

这是一个简化版的实现,与完整的 Webpack 相比:

已实现

✅ 编译器,✅ 编译对象,✅ 模块系统,✅ 依赖解析,✅ 代码块,✅ 加载器,✅ 钩子系统。

未实现

❌ 完整的插件生态,❌ 代码分割,❌ Tree-shaking,❌ Source Map,❌ HMR,❌ 缓存系统。

总结

这个简化版的实现展示了 Webpack 的核心概念和架构设计。编译器负责整个编译的生命周期管理,协调各个阶段的工作;编译对象作为单次编译的上下文,保存了编译过程中的所有状态;模块是 Webpack 的基本构建块,每个文件都被当作一个模块来处理;解析器负责提取模块之间的依赖关系,构建出完整的依赖图;代码块是模块的集合,用于打包输出;加载器则负责将各种类型的文件转换为 Webpack 能够处理的模块。通过这个简化版本,可以深入理解 Webpack 的工作原理和设计思想。