前言
此系列文章作为笔记,用于记录分析 webpack 源码主流程的过程。
概览
目录
根据 webpack 构建流程及相关,本系列文章一共分为以下章节:
流程图
webpack 构建流程图:
![](https://img-blog.csdnimg.cn/img_convert/0e9466610eefdd2b65287b23497a9bcd.webp?x-oss-process=image/format,png)
本系列代码环境
"devDependencies": {
"@babel/core": "^7.7.5",
"@babel/preset-env": "^7.7.6",
"@fe_korey/test-loader": "^1.0.0",
"babel-loader": "^8.0.6",
"html-webpack-plugin": "^3.2.0"
},
"dependencies": {
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
}
复制代码
版本不同,源码略微有差异。
本项目 demo 开源在github,欢迎交流学习。
分析源码前的一系列准备工作
采用 vscode 来打断点调试分析。
配置 vscode
//launch.json"configurations":[{"type":"node","request":"launch","name":"Launch Program","runtimeExecutable":"npm","runtimeArgs":["run","debug"],"port":5858,"console":"externalTerminal","skipFiles":["<node_internals>/**/*.js"]}]复制代码
配置 npm script
"scripts":{"debug":"node --inspect-brk=5858 ./node_modules/.bin/webpack"},复制代码
了解 webpack 的插件架构
webpack 从配置初始化到打包完成定义了一个生命周期,在这个生命周期中的每一个阶段定义一些不同的功能。webpack 的流程同样也是一个事件驱动的架构,利用插件系统 tabpable,通过 发布订阅事件 来实现所有内部的,外部扩展的功能。
了解 webpack 的核心模块
webpack 的构建是通过 Compiler 控制构建流程,Compilation 解析,ModuleFactory 生成模块,Parser 解析源码,Template 渲染代码,最后输出打包后的文件。
了解 tapable
tabpable 本质就是一个事件发布订阅机制,支持同步异步,使用xxx.tap之类的来事件订阅,使用xxx.call之类的来进行事件发布。相关文档查阅:
demo 准备
npm 安装
npm i webpack-cli webpack
npm i @babel/core @babel/preset-env babel-loader -D
npm i @fe_korey/test-loader -D
复制代码
demo 文件
我们以 development 模式为例,暂时忽略支线剧情,只分析探索 webpack 的打包主流程。
//src/a.js
import { add } from 'Src/b';
import('./c.js').then(m => m.sub(2, 1));
const a = 1;
add(3, 2 + a);复制代码
//src/b.js
import { mul } from '@fe_korey/test-loader?number=20!Src/e';
export function add(a, b) {
return a + b + mul(10, 5);
}
export function addddd(a, b) {
return a + b * b;
}
复制代码
//src/c.jsimport { mul } from'Src/d';
import('./b.js').then(m => m.add(200, 100));
exportfunctionsub(a, b) {
return a - b + mul(100, 50);
}
复制代码
//src/d.jsexportfunctionmul(a, b) {
const d = 10000;
return a * b + d;
}
复制代码
//webpack.config.jsvar path = require('path');
module.exports = {
entry: {
bundle: './src/a.js'
},
devtool: 'none',
output: {
path: __dirname + '/dist',
filename: '[name].[chunkhash:4].js',
chunkFilename: '[name].[chunkhash:8].js'
},
mode: 'development',
resolve: {
alias: {
Src: path.resolve(__dirname, 'src/')
}
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader'
}
]
}
]
}
};
复制代码
//babel.config.js
module.exports = {
presets: ['@babel/env']
};复制代码
一颗坚定且耐操的心
为什么要阅读它?
因为可以让我们更好的理解海量配置,知道每一个配置在打包的具体哪个环节
在对构建流程进行优化时能更清楚的根据过程思考优化点
还可以学习下在这种大型项目里,如何实现稳定的架构和良好的扩展性
对自定义开发一些 plugin 和 loader 有更深刻的理解
了解它的一些代码设计方式能给我们的日常搬砖带来一些新的启发
最重要的还是想满足自己的好奇欲,想知道在这犀利的打包背后,到底是怎么实现的。
webpack 里包含数不清的变量和钩子,海量插件,这些足以让你怀疑人生,请务必保持一颗耐操的心。 一切准备就绪后,进入 vscode 的调试模式!
作者:Korey
链接:https://juejin.cn/post/6844904047221145613
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。