这是我参与「第五届青训营 」笔记创作活动的第11天。
本堂课重点内容
本堂课从webpack定义,使用方法,loader和插件四部分来对webpack的使用进行了入门。
详细知识点介绍
前端项目由资源构成,如果我们手动管理资源的话,可能有以下问题:
- 依赖手工,比如有50个JS文件...操作,过程繁琐
- 当代码文件之间有依赖的时候,就得严格按照依赖顺序书写
- 开发与生产环境一致,难以接入TS或JS新特性
- 比较难以接入Less、Sass等工具
- JS、图片、CSS资源管理模型不一致
因此,前端也出现了很多项目工程化工具,如webpack,rollup.js,vite,Gulp等。
对于webpack来说,其本质上是一种前端的资源编译的打包工具。
webpack基础使用
- 安装依赖
npm i -D webpack webpack-cli - 编辑配置文件
- 执行编译命令
npx webpack
工作核心流程:
- 入口处理:从
entry文件开始,启动编译流程 - 依赖解析:从
entry文件开始,根据requireorimport等语句找到依赖语句 - 资源解析:根据
module配置,调用资源转移器,将png css等非标准JS资源转译为JS内容 - 资源合并打包:将转译后的资源内容合并打包为可直接在浏览器运行的JS文件
对2 3 进行递归调用,知道处理完所有资源。
关于webpack的使用方法,基本都围绕着“配置”展开,这些配置可以大致划分为两类:
- 流程类:作用于流程的某些环节,直接影响打包效果的配置项
- 工具类:主流程之外,提供更多工程化能力的事项
按使用频率:
entry/outputmodule/pluginsmodewatch/devServer/devtool
entry/output
项目出口入口
module
导入CSS
借助
loader导入CSS,test用于过滤文件,use中写入装好的loader。
接入Babel:
生成HTML:
使用HTMLWebpackPlugin可以自动生成HTML,通过对插件的配置进行对HTML的定制。
devServer
HMR模块热替换:
module.exports = {
devServer:{
hot:true;
},
plugins:[new HTMLWebPackPlugin()],
// 持续监听文件变化
watch:true,
}
tree-shaking
对dead code进行删除。
module.exports = {
mode: 'production',
optimization:{
useExports: true
}
}
loader
webpack只认识JS代码,为了处理非标准JS资源,设计出资源翻译模块——Loader,用于将资源翻译为标准JS。
使用loader:
- npm安装
- 在
module中添加处理的配置(test,use等)
链式调用规则:less-loader => css-loader => style-loader
less-loader:实现less=>CSS的转换css-loader:将CSS包装成类似module.exports = "${CSS}"的内容,包装后符合JS语法style-loader:将style模块包进require语句,并在运行时调用injectStyle等函数将内容注入页面的style标签。
特点:
- 链式执行
- 支持异步执行
- 分为normal、patch两个模式
如何编写loader:
module.exports = function(source,sourceMap?,data?){
// source 为 loader 的输入
// 可能是文件内容,也可以是上个loader处理的结果
return source;
}
插件
为什么很多知名工具都有插件架构?
webpack编译是一个特别复杂的过程,那么:
- 新人需要了解整个流程细节,上手成本高
- 功能迭代成本高,牵一发而动全身
- 功能僵化,作为开源项目而言缺乏成长性
心智成本高=>可维护性低=>生命力弱
插件架构的精髓:对拓展开放,对修改封闭。
首先,插件围绕着钩子展开,钩子可以理解为当webpack运行到某个步骤时触发事件。
钩子的核心信息:
- 时机:编译过程的特定节点
- 上下文:通过tabable提供的回调机制
- 交互:在上下文参数对象中附带了很多存在
side effect的交互接口,插件可以通过这些接口改变