【webpack系列】6. 从源码角度深度剖析html-webpack-plugin执行过程

1,496 阅读3分钟

之前文章介绍了webpack的plugin插件是如何运行的,但是对于某个特定的插件具体如何执行的还是不太清楚,这篇文章从实例的角度来剖析html-webpack-plugin的执行流程,相信通过这篇文章可以更好的理解插件原理。

1. 为什么需要html-webpack-plugin插件

主要用来自动生成index.html,并将需要的静态资源插入到html中。如果没有这个插件,每次都需要手动写html文件,影响开发效率和体验。

2. html-webpack-plugin插件实现了哪些功能

通过打包结果可见,主要功能是自动生成html文件,需要在配置webpack.config.js中是增加了插件配置:

 // 传入模板
 new HtmlWebpackPlugin({
     template: './src/index.html',  // html模板路径,可知插件应该具备读取文件和识别html的功能
     title: '标题'  // 浏览器标题内容,可以替换标题
   }),

 // 不传模板
 new HtmlWebpackPlugin()

不传模板使用插件自带的模板(自定义模板注意title赋值写法)

69fc882707f9f2d4ee55326aaa508937.png

自定义模板的话会进行覆盖 e522df187c6eaaed3b6bb61f1c2576b4.png

这个title怎么替换的?templateParametersGenerator可以拿到配置数据

image.png

然后loader加载时进行转换

ded3496e09c0c0a86044acae14cbcc86.jpg

我们反向思考下,要生成index.html文件,需要添加entry的入口文件和通过compiler的emit周期钩子函数输出文件,然而在生成html前还需要插入js和css等静态资源文件,这些文件可以通过compilation的chunks中获取。因此这个插件基本就是实现了这几个关键功能:

  • 向entry中添加html的入口文件(还需要识别html的loader,插件自带);
  • 向html中添加静态资源文件,例如js、css和favicon等;
  • 输出html文件;

3. html-webpack-plugin插件是怎么实现的

基于插件实现的功能进行描述核心实现流程,依次如下:

3.1. 如何向entry中添加入口文件?

之前分析过webpack整体执行流程,入口是在compilation的make阶段处理的,复习下整个流程: image.png

(1)插件通过apply得到compiler对象,通过compiler可以拿到compilation,然后创建一个子编译对象(不具备整个编译流程,只具备模块和chunks生成),然后通过SingleEntryPlugin向entry添加了html入口,如图:

9e95292689eb10bb678464eca2efdc14.png

image.png

3.2. 如何向html中添加静态资源文件

通过compiler给compilation添加了处理html的钩子函数,在emit前将静态资源添加到html中再输出即可。如图所示:

注册相关钩子函数

image.png

通过compilation可以获得所有的js、css等资源内容

image.png

依次执行钩子函数,实现向compilation的chunks添加资源

image.png

3.3. 如何输出html文件

通过上面两步,入口文件和html文件内容都已经准备好,利用emit钩子生命周期函数通过compilation.getAssets()得到所有静态资源内容,根据outputName和资源内容即可写入文件。

image.png

4. 总结

html-webpack-plugin插件主要在webpack主流程的make阶段前添加了entry入口和emit阶段前添加了静态资源,可见webpack强大的可扩展性。

其他插件原理应该也是类似的,借助webpack的compiler和compliation提供的功能,在合适的时间加入处理逻辑实现想要的功能,通过灵活的插件机制可以解决业务中的一些特殊场景(一些特殊文件的单独打包,实现不需要修改代码的适配)。

相信通过这篇文章对webpack的插件机制有了更深一步理解,感谢点赞支持~

附上历史文章:

【webpack系列】从源码角度分析webpack打包产出及核心流程

【webpack系列】从源码角度分析loader是如何触发和执行的

【webpack系列】webpack是如何解析模块的

【webpack系列】webpack的plugin插件是如何运行的

【webpack系列】从源码角度分析webpack热更新流程