前端工程化已成为前端工程师必须要掌握的知识点。webpack凭借其强大的生态和优秀的功能慢慢形成主导地位(rollup和vite 也同样优秀),从开始学会如何使用配置,慢慢的进一步深入理解其原理和流程,从而对整个工程化流程有个全面且系统的认知,进而逐步消化形成自己的知识体系。
webpack是一个JavaScript应用程序的静态模块打包器(module bundler)。它会通过递归形式构建一个资源与模块之间的依赖关系图(dependency graph),并根据此构建一个或多个bundle。
主要功能:模块打包编译兼容功能扩展
development(开发模式)
production(生产模式)
module.exports = {
mode: 'production'
};
指定webpack应该使用哪个模块来作为构建内部依赖图的起点.
通过entry设置,默认./src
module.exports = {
entry: './path/xxx/file.js'
};
指定webpack输出所创建的bundles,以及如何命名文件
通过output设置, 默认 ./dist
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
};
1>. loader:文件转译器.将文件进行如编译,压缩等处理转译成webpack支持打包的模块.
2>. 本质上是一个函数,支持链式调用,支持同步,异步函数
3>. loader是顺序执行的,从上往下.
4>. 发生在打包之前.
module.exports = {
module: {
rules: [
{
test: /xxx/,
use: ["xxx-loader"]
}
]
}
}
常用loader
style-loader: 将css编译完成后样式挂载到页面style标签上
css-loader: 识别.css文件,需配合style-loader共同使用
sass-loader: css预处理器,识别转译.scss文件
postcss-loader: 补充css样式各种浏览器内核前缀
ts-loader: 编译识别.ts文件
html-loader: 将html代码片段赋值给DOM元素内容使用
file-loader: 处理文件类型资源,返回值为publicPath为准
url-loader: 处理图片类型资源.与file-loader不同的是:可以设置图片大小进行不同的操作,大于则将图片进行打包,否则图片转换为base64后合并
eslint-loader: 检查代码规范以及语法错误
vue-loader: 编译.vue文件
1>. 扩展插件,用于实现loader之外的功能.
2>. 基于Tapable实现的发布,订阅机制之上,在webpack构建过程中的特定时机注入扩展逻辑来改变输构建结果.
3>. 持续整个webpack构建过程.
4>. 本质是一个具有apply属性的js对象. apply属性会被complier调用.
plugins: [
new webpack.optimize.UglifyJsPlugin(),
...
]
常用plugin
copy-webpack-plugin: 将已经存在的单个文件或整个目录复制到构建目录
clean-webpack-plugin: 清空上次构建成功后的所有文件,保证每次构建生成的文件都是最新的
webpack.HotModuleReplacementPlugin: 模块热更新(HRM):用于应用程序运行期间替换,添加,删除模块,无需重新加载整个页面。1>. devServe中配置hot:true;2>. 此模块绝对不能用于生产环境.
webpack.DefinePlugin:创建一个在编辑时可以配置的全局常量
webpack-bundle-analyzer: 用于分析应用内各个模块的大小
SplitChunksPlugin:代码分割
UglifyJsPlugin: 代码压缩
I18nWebpackPlugin: 代码语言国际化
CompressionWebpackPlugin: gzip压缩,经常用于生产环境
SpeedMeasureWebpackPlugin:分析构建打包速度
image-minimizer-webpack-plugin:图片压缩
- 从配置文件,配置对象,shell参数中读取并与默认配置合并得出最终配置参数
- 用最终的配置参数创建complier对象
- 初始化所有plugins扩展
- 根据entry找出所有的入口
- 根据entry调用loader将模块转译为标准JS内容
- 调用JS解释器(bable)将内容转换为AST对象并从中找到依赖的模块
- 递归找出所有依赖模块后,生成模块依赖关系图(dependency graph)
- 根据依赖关系图组装成一个个chunk,并将chunk转换成单独的asset文件加入到文件输出列表
- 根据输出配置把文件写入到文件系统
- 全局单例编译器的实例
- 把控整个webpack打包构建流程
- 每次热更新和重新构建,complier都会生成新的compilation对象
每次构建的上下文对象,包含档次构建所需要的所有信息.
全称:Hot Module Replacement,模块热更新.
在保持页面状态情况下动态替换更新资源模块,无需刷新页面
- webpack将资源托管至WDC(webpack-dev-serve), 同时以Runtime方式注入HRM客户端代码
- 浏览器加载页面后,与WDC建立Websoket连接
- webpack监听到文件变化,增量构建变更模块,并通过websoket推送并携带hash
- 浏览器接收hash事件后,请求mainfest资源文件并确认变更范围并增量加载变更模块
- webpack触发变更模块module.hot.accept回调,执行变更逻辑完成模块更新
一种基于ES Module规范的 Dead Code Elimination技术
作用: 在运行过程中静态分析模块之间的导入导出,确认未被使用的导出值并将其删除,以此实现打包优化.
使用ESM规范编写模块代码
配置optimization.usedExports为true,启动标记功能
启动代码优化功能
配置mode=production
配置optimization.minimize=true
提供optimization.minimizer数组
- 【标记】: 收集模块导出变量并记录到模块依赖关系图的变量中,遍历依赖关系图中变量标记模块导出未被使用的值.
- 【构建】利用Terser删除编辑的值
webpack插件架构的核心支架。本质上围绕Tapable实现了在编辑过程中的一种发布,订阅模式的插件机制。
Tapable提供了一系列事件的发布订阅API, webpack编译过程中利用此API注册事件,从而实现在特定时机触发扩展逻辑执行并影响输出结果