webpack源码解读
本文只是笔者初次学习 webpack 源码所写(感谢依柳诚提供的阅读 webpack 源码的思路),供以后精读作目录使用。
vscode debug
lib/index.js 入口
lib/webpack.js
const webpack = require('../lib/index.js') // 直接使用源码中的webpack函数const config = require('./webpack.config')const compiler = webpack(config)校验 options
createCompiler(options)创建 compiler 对象并放回
//精简版const createCompiler = (rawOptions) => {// lib/compiler.jsconst compiler = new Compiler(options.context)if (Array.isArray(options.plugins)) {for (const plugin of options.plugins) {if (typeof plugin === 'function') {plugin.call(compiler, compiler)} else {//执行插件的apply方法。这也是为啥自定义插件要有一个apply方法的原因plugin.apply(compiler)}}}//对options配置项 进行兜底赋值applyWebpackOptionsDefaults(options)//根据options中配置的target属性,加载webpack默认的插件;并注册一些钩子等待后续调用new WebpackOptionsApply().process(options, compiler)return compiler}
lib/compiler.js
compiler.run((err, stats) => {if (err) {console.error(err)} else {console.log(stats)}})调用 run 方法
run 方法中调用编译方法 compile
compile 方法调用 make 钩子
make
在EntryPlugin
中注册//lib/EntryPlugin.jscompiler.hooks.make.tapAsync('EntryPlugin',(compilation, callback) => {const { entry, options, context } = thisconst dep = EntryPlugin.createDependency(entry, options)compilation.addEntry(context, dep, options, (err) => {callback(err)})})回溯,EntryPlugin 在 EntryOptionPlugin 实例化,EntryOptionPlugin 在 lib/WebpackOptionsApply 中实例话并调用 apply 方法。在 createCompiler 中会实例化 WebpackOptionsApply,一切明朗。
//根据options中配置的target属性,加载webpack默认的插件;并注册一些钩子等待后续调用new WebpackOptionsApply().process(options, compiler)EntryPlugin
主要执行了 compilation 中的addEntry
方法this.addEntry --> this.addModuleChain --> this.handleModuleCreation --> this.addModule --> this.buildModule --> this._buildModule --> module.build
make 钩子回调触发 compilation.seal() 打包 chunks 和 assets
emitAssets 输出打包之后的文件到 output
参考
- 第一张图片记不得从哪里下载的了,有道友知道麻烦评论,我会加上。如有侵权会删除
- 掘金-依柳诚-Webpack 源码解读:理清编译主流程