Compilation工作流程
Compilation工作流程
Webpack的Compilation工作流程是其核心机制之一,负责将模块依赖图转换为最终的可执行代码。整个过程涉及多个阶段,包括初始化、构建、优化和生成输出文件。
初始化阶段
Webpack启动时会创建Compilation
实例,该实例贯穿整个构建过程。初始化阶段主要完成以下操作:
class Compilation {
constructor(compiler) {
this.hooks = {
buildModule: new SyncHook(['module']),
succeedModule: new SyncHook(['module']),
// ...其他hooks
};
this.modules = new Set();
this.chunks = new Set();
}
}
环境参数和基础配置在此阶段确定,包括:
- 解析
entry
配置项 - 初始化
NormalModuleFactory
等工厂类 - 注册内置插件的基础hooks
构建阶段
入口解析
从配置的entry出发,开始构建模块依赖图:
// webpack/lib/Compilation.js
addEntry(context, entry, name, callback) {
this._addModuleChain(context, entry, (err, module) => {
// 处理入口模块
});
}
模块加载
使用loader
系统处理不同资源类型:
// 示例loader链配置
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader'],
exclude: /node_modules/
}
]
}
每个模块会经历:
- 路径解析(resolve)
- 加载原始内容
- loader转换
- AST解析
依赖收集
通过acorn
生成AST分析依赖关系:
// 简化的依赖分析过程
const dependencies = [];
traverse(ast, {
ImportDeclaration(path) {
dependencies.push(path.node.source.value);
}
});
优化阶段
模块合并
SplitChunksPlugin
等优化插件开始工作:
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000
}
}
Tree Shaking
基于ES Module的静态分析移除无效代码:
// 原始代码
export function used() {...}
export function unused() {...}
// 打包后只会包含used()
代码生成
将优化后的模块转换为可执行代码:
// webpack/lib/Template.js
generate() {
return {
sources: new RawSource(code),
runtimeRequirements: new Set()
};
}
输出阶段
资源生成
根据output
配置生成最终文件:
// 输出配置示例
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true
}
文件写入
通过compiler.outputFileSystem
接口写入文件系统:
// webpack/lib/Compiler.js
emitAssets(compilation, callback) {
const outputFiles = {};
// 生成文件内容...
this.outputFileSystem.writeFile(
targetPath,
content,
callback
);
}
高级处理流程
热更新处理
开发环境下特殊的compilation流程:
// webpack-dev-server中热更新处理
compiler.hooks.done.tap('HotModuleReplacement', stats => {
server.sendMessage(clients, 'hash', stats.hash);
});
持久化缓存
利用cache
配置加速二次构建:
// 缓存配置示例
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename]
}
}
自定义处理
通过插件扩展compilation流程:
class MyPlugin {
apply(compiler) {
compiler.hooks.compilation.tap('MyPlugin', compilation => {
compilation.hooks.optimize.tap('MyPlugin', () => {
// 自定义优化逻辑
});
});
}
}
性能优化策略
并行处理
使用thread-loader
加速构建:
{
loader: 'thread-loader',
options: {
workers: require('os').cpus().length - 1
}
}
增量编译
利用watch
模式只重新编译变更模块:
webpack --watch
模块联邦
跨项目共享编译结果:
// 模块联邦配置
new ModuleFederationPlugin({
name: 'app1',
exposes: {
'./Button': './src/Button.js'
}
});
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:Compiler核心类解析