Webpack知识体系 | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的第13天 与大家分享Webpack的知识体系、基础知识,包括Webpack的学习方法等,不足之处欢迎大家批评指正!
01 为什么要学习Webpack?
- 理解前端“工程化”概念、工具、目标
- 一个团队总要有那么几个人熟悉webpack,某种程度上可称为个人核心竞争力
- 高阶前端必经之路
02 什么是Webpack
引入
- 前端项目由什么构成?——资源
可以手动管理这些资源
- 手动管理的缺点
- 依赖手工,比如有50个JS文件...操作,过程繁琐
- 当代码文件之间有依赖时,就得严格按依赖顺序书写
- 开发与生产环境一致,难以接入TS或JS新特性
- 比较难接入Less,Sass等工具
- JS、图片、CSS资源管理模型不一致
- 直到出现工程化工具
Webpack的本质
Webpack本质是一种前端资源编译、打包工具
- 多份资源打包成一个Bundle
- 支持 Babel,Eslint,TS,CoffeScript,Less,Sass
- 支持模块化处理css,图片等资源文件
- 支持 HMR + 开发服务器
- 支持持续监听、持续构建
- 支持代码分离
- 支持Tree-shaking
- 支持Sourcemap
03 使用Webpack
示例
- 安装
- 编辑配置文件
- 执行编译命令
核心流程——极度简化版
- 入口处理(Get Start)
从entry文件开始,启动编译流程
2.依赖解析(Dependencies Lookup)
从entry文件开始,根据require or import等语句找到依赖资源
- 资源解析(Transform)
根据module配置,调用资源转移器,将png,css等非标准资源转译为JS内容
- 资源合并打包(Combine Assets)
将转译后的资源内容合并打包为可直接在浏览器运行的JS文件
模板化 + 一致性
使用Webpack
使用围绕配置展开,大致划分为两类:
- 流程类
作用于流程中某个 or 若干个环节直接影响打包效果的配置项
- 工具类
主流程之外,提供更多工程化能力的配置项
流程类配置
- 入口处理(Get Start)
输入:
entry
context
2.依赖解析(Dependencies Lookup)
模块解析:
resolve
externals
- 资源解析(Transform)
模块转译:
module
- 资源合并打包(Combine Assets)
后处理:
optimization
mode
target
配置总览
按使用频率:
- 'entry/output'
- 'module/plugins'
- 'mode'
- 'watch/devServer/devtool'
Webpack官方配置文档:webpack.js.org/configurati…
使用Webpack方法
- 声明入口
entry
- 声明产物出口
output
- 运行
npx webpack
处理CSS
- 安装Loader
- 添加
module处理css文件
思考
- Loader有什么作用?为什么这里要用css-loader,style-loader?
- 与旧时代——在HTML文件中维护css相比,这种方式的优劣?
- Less,Sass,Stylus这类的预编译框架,如何在Webpack中接入?
参考资料:
CSS-loader: github.com/webpack-con…
Webpack 原理系列七:如何编写loader: mp.weixin.qq.com/s/TPWcB4MfV…
Style-loader: webpack.js.org/loaders/sty…
接入Babel
- 安装依赖
-
声明产物出口
output -
执行
npx webpack
思考
- Babel 的具体功能?
- Babel 与Webpack 分别解决了什么问题?为何二者能协作到一起? 参考资料:
Babel-Loader: webpack.js.org/loaders/bab…
Babel官网:babeljs.io/
@babel/preset-env:babeljs.io/docs/en/bab…
@babel/preset-react: babeljs.io/docs/en/bab…
@babel/preset-typescript:babeljs.io/docs/en/bab…
生成HTML
- 安装依赖
- 声明产物出口
output
- 执行
npx webpack
- 执行结果
思考
- 相比于手工维护HTML,这种自动生成方式的优缺点?
参考资料:
HtmlWebpackPlugin:webpack.js.org/plugins/htm…
工具线
HMR(Hot Module Replacement)模板热替换
- 开启HMR
- 启动Webpack
参考资料:
Webpack 原理系列十:HMR 原理全解析:mp.weixin.qq.com/s/cbYMpuc4h…
Tree-Shaking
Tree-Shaking——树摇,用于删除Dead Code
模板导出了,但未被其它模块使用
Dead Code
- 代码没有被用到,不可到达
- 代码的执行结果不会被用到
- 代码只读不写
- ...
Dead Code的情况:
开启Tree-shaking:
mode:"production"
optimization.usedExports:true
PS:对工具类库如 Lodash 有奇效
其它工具
- 缓存
- Sourcemap
- 性能监控
- 日志
- 代码压缩
- 分包
- ...
04 进阶篇:理解Loader
问题
Webpack只认识JS
- 为了处理非标准JS资源,设计出资源翻译模块——Loader
- 用于将资源翻译为标准JS
使用Loader
- 安装Loader
- 添加
module处理 CSS 文件
认识Loader——链式调用
- Less-loader: 实现less => CSS的转换
- CSS-loader: 将CSS包装成类似 module.exports = "${css}" 的内容,包装后的内容符合JavaScript的语法
- style-loader: 将css模块包进 require 语句,并在运行时调用 injectStyle 等将内容注入到页面的style标签
其它特性
特点:
- 链式执行
- 支持异步执行
- 分 normal, pitch 两种模式
如何编写Loader
参考资料:
Webpack 原理系列七:如何编写loader:mp.weixin.qq.com/s/TPWcB4MfV…
常见Loader
站在使用角度,建议掌握常见Loader的功能、配置方法
05 进阶篇:理解插件
设计插件原因
- Webpack编译流程复杂
- 新人需要了解流程细节,上手成本高
- 功能迭代成本高,牵一发动全身
- 功能僵化,作为开源项目而言缺乏成长性
- ...
- 心智成本高 => 可维护性低 => 生命力弱
- 插件架构精髓:对扩展开放,对修改封闭
Webpack的很多功能也是基于插件实现的
- 使用html-webpack-plugin
- 使用 html-webpack-plugin + DefinePlugin
理解插件
插件围绕“钩子”展开
- 钩子的核心信息
- 时机:编译过程的特定节点,Webpack会以钩子形式通知插件此刻正在发生什么事情
- 上下文:通过 tapable 提供的回调机制,以参数方式传递上下文信息
- 交互:在上下文参数对象中附带了很多存在 side effect 的交互接口,插件可以通过这些接口改变
时机:compier.hooks.compilation
参数:compilation等
交互:dependencyFacories.set
思考:
- Loader与插件有什么区同点?
- “钩子”有什么作用?如何监听钩子函数?
参考资料:
[源码解读] Webpack 插件架构深度讲解:mp.weixin.qq.com/s/tXkGx6Ckt…
[万字总结] 一文吃透 Webpack 核心原理: mp.weixin.qq.com/s/SbJNbSVzS…
小结:Webpack5知识体系
06 学习方法
方法
- 入门应用
- 理解打包流程
- 熟练掌握常用配置项、Loader、插件的使用方法,能够灵活搭建集成Vue、React、Babel、Eslint、Less、Sass、图片处理等工具的Webpack环境
- 掌握常见脚手架工具的用法,例如:Vue-cli、create-react-app、@angular/cli
- 进阶
- 理解Loader、Plugin机制,能够自行开发Webpack组件
- 理解常见性能优化手段,并能用于解决实际问题
- 理解前端工程化概念与生态现状
- 大师级
- 阅读源码,理解Webpack编译、打包原理,甚至能够参与共建