webpack 作为前端最火的构建工具, 是前端自动化工具链最重要的部分, 使用门槛较高. 本系列是笔者自己的学习记录, 比较基础, 希望通过问题 + 解决方式的模式, 以前端构建中遇到的具体需求为出发点, 学习 webpack 工具中相应的处理办法.(本篇中的参数配置及使用方式均基于 webpack4.0 版本)
一. webpack 中的 html
对于浏览器而言, html 文件是用户访问的入口点, 也是所有资源的挂载点, 所有资源都是通过 html 中的标记来进行引用的. 而在 webpack 的构建世界里, html 只是一个展示板, 而 entry 参数中指定的 javascript 入口文件才是真正在构建过程中管理和调度资源的挂载点, html 文件中最终展示的内容, 都是 webpack 在加工并为所有资源打好标记以后传递给它的, 业界将这种有别与浏览器的模式称之为 "webpack 的逆向注入".
二. html 文件基本处理需求
前端项目可以大致分为 单页面应用 和 多页面应用, 现代化组件中的 html 文件主要作为访问入口文件, 是 < style> 样式标签和 < script > 脚本标签的挂载点, 打包中需要解决的基本问题包括:
个性化内容填充 (例如页面标题, 描述, 关键词)
多余空格删除 (连续多个空白字符的合并)
代码压缩 (多余空白字符的合并)
去除注释
三. 入口 html 文件的处理
3.1 单页面应用打包
对于入口 html 文件的处理直接使用
html-webpack-plugin
插件来设置一定的配置参数即可, 详细的配置参数可以参考其 github 地址: html-webpack-plugin 项目地址 https://github.com/jantimon/html-webpack-plugin , 在此直接给出基本用法示例.
webpack.config.js 配置:
index.html 模板文件 (构建生成的入口页面是以此为模板的):
打包后生成的 index.html:
- <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><div><p>tony stark</p><p>bruce banner </p></div><script type="text/javascript" src="main.boundle.js"></script></body></html>
- 3.2 多页面应用打包
- 如果项目中有多个页面, 那么打包的时候需要考虑两个基本问题:
- 1. 如何自动生成多个页面?
- 2. 如果引用中存在公共的模块, 怎样才能提取公共模块?
- 为了演示多页面应用打包的场景, 我们来构建如下的一组示例项目及其依赖关系:
- 多页面应用的基本结构理解起来并不复杂, 可以将其看做是多个单页面应用的组合, 在 webpack 中需要进行一些配置调整:
- entry 参数需要配置多个依赖入口文件:
- entry:{
- "main":__dirname + "/src/indexController.js",
- "about":__dirname + "/src/aboutController.js",
- "list":__dirname + "/src/listController.js",
- },
- html 文件则需要分别引用对应的入口文件并生成对应的访问入口:
- plugins:[
- //index.html
- new HtmlWebpackPlugin({
- title:'MainPage',
- template:'src/index.html',
- filename:'index.html',
- templateParameters:{
- param1:'tony stark',
- param2:'bruce banner'
- },
- chunks:['main'],
- }),
- //about.html
- new HtmlWebpackPlugin({
- title:'AboutPage',
- template:'src/about.html',
- filename:'about.html',
- templateParameters:{
- param1:'tony stark',
- param2:'bruce banner'
- },
- chunks:['about'],
- }),
- //list.html
- new HtmlWebpackPlugin({
- title:'ListPage',
- template:'src/list.html',
- filename:'list.html',
- templateParameters:{
- param1:'tony stark',
- param2:'bruce banner'
- },
- chunks:['list'],
- }),
- ],
- 可以看到在生成 html 文件时已经为其单独引用了 chunks 数组中指定的模块, 这使得对应的页面生成时只依赖自己需要的脚本.
- 1. 关于公共模块提取
- 上一小节解决了多页面应用的基本打包的需求, 从得到的打包后的模块中, 很容易看出它存在重复打包的问题, eventbus.js 这个公共库被 indexController.js 和 aboutController.js 中均被引用, 但在不同的 chunks 中被重复打包, 当公共部分的体积较大时, 这样的方式明显是不能接受的. 实际上分包问题并不是多页面应用中才存在的, 而且是非常复杂的, 它不仅要考虑公共模块本身的大小, 模块之间的引用关系, 还需要考虑同步引用和异步引用等等非常多的问题, 笔者尚未研究清楚.
- webpack1-3 的版本中使用 commonsChunkPlugin 插件来解决这个问题, 在 4.0 以上的版本中废弃了原有方法, 改为使用
- optimization.splitChunks
- 和
- optimization.runtimeChunk
- 来解决优化 chunk 拆分的问题, 关于两者的区别可以看webpack4: 连奏中的进化这篇博文.
- 2. 组件模板 html 文件的处理
- 在基于 Angular 的项目中或许你会需要处理此类问题. github 上点赞较多的
- Angular-webpack-starter
- 项目对于 html 文件的处理是直接使用 raw-loader 当做文本文件处理, 推测其内部将 html 文件中的内容当做模板字符串使用并在框架内部进行了加工.
- 需要注意的是,
- html-webpack-plugin
- 插件是依赖于 html-loader 而工作的, 当你显式使用 /\.html$/ 作为规则来筛选文件时, 同样会选择到作为入口文件的 html 资源, 从而造成冲突报错. 在 Angularjs1.X 项目中可考虑使用 ngTemplage-loader 插件.
- 四. 小结
- 本文使用的 html 文件是较为简单的, 仅包含基本的标签和属性, 并未包含其他资源引用 (样式, 图片等), 毕竟 webpack 的组成部分太过庞杂, 去除干扰信息有针对性的学习更容易理解. 资源管理及定位将在后续的章节阐述.
来源: https://www.cnblogs.com/dashnowords/p/9478777.html