这是我参与「第五届青训营 」笔记创作活动的第17天。
一、本堂课的重点内容
- 理解前端“工程化”概念、工具、目标,Webpack很复杂,学习成本很高,某种程度上可以成为个人的核心竞争力,高阶前端必经之路
- Webpack打包核心流程,关键配置项
- 如何学习Webpack:学会灵活应用->学会扩展Webpack->源码级理解Webpack打包编译原理
二、详细知识点介绍
Webpack介绍
前端项目由多种资源构成,HTML、css、js、图片、音频、视频、字体、配置文件...
可以通过手动管理这些资源,但流程繁琐、依赖复杂、难以接入Less、Sass等预编译工具、针对JS,图片,CSS的资源管理模型不一致...
09年左右,出现了一批“前端工程”化的工具,gulp、require.js、rollup.js、browserify、Vite、Webpack等,用于解决js文件模块化等。
Webpack本质上是一种前端资源编译、打包工具
Webpack会把非js文件进行编译,让它变成一个js文件,然后把编译好的内容进行打包,变成一个Bundle文件。
- 多份资源文件打包成一个Bundle
- 支持Babel、Eslint、TS、CoffeScript、Less、Sass等,这些可以变成Webpack的一个组件,一个工作流中的步骤
- 支持模块化处理CSS,图片等资源文件,统一的源文件管理模型
- 支持HMR+开发服务器
- 支持持续监听、持续构建
- 支持代码分离
- 支持Tree-shaking
- 支持SourceMap
- ...
Webpack使用流程
多个资源合并成一个资源。
模块化、一致性
步骤:
- 安装依赖
npm i -D webpack webpack-cli - 编辑配置文件 webpack.config.js,非常复杂
- 执行编译命令
npx webpack
- 读entry文件,开始编译
- 找到当前文件对其他文件的依赖
- 将非js资源转为标准js,递归处理
- 资源合并打包,包括插入运行时代码,优化代码,混淆,压缩
Webpack的使用基本是围绕配置文件展开,包括:
- 流程类:作用于流程中某个或若干环节,直接影响打包效果的配置项,属于Webpack工作流程的配置项
- 工具类:主流程之外,提供更多工程化能力的配置项
Webpack有上百个配置,每个配置都有丰富的内涵
流程相关配置项:
- 入口处理
- entry,项目入口文件
- context,Webpack运行时从哪个文件夹找资源
- 模块解析
- resolve
- externals
- 模块转译
- module,很复杂
- 后处理
- optimization
- mode
- target
工具相关配置项
- 开发效率类
- watch
- devtool
- devServer
- 性能优化
- cache
- performance
- 日志类
- stats
- infrastructureLogging
- 其他
- amd
- bail
最常用配置项
- entry/output,这2个是必需的
- module/pluigns,插件
- 处理js里引用的css需要用module定义一个loader去处理,详见例子
- 处理css需要安装style-loader和css-loader依赖,
npm add -D css-loader style-loader,npm add和npm install等价,是npm install的别名。
- mode,设为production时,会压缩,产物会简洁很多
- watch/devServer/devtool
Loader:在Webpack中用于处理不同的资源文件
Webpack处理css
上文和例子中已经提过了,概括讲:
- 安装依赖,
npm add -D css-loader style-loader - 编辑配置项
module: { rules: [{ test: /\.css$/,//过滤条件,满足test规则的采用loader处理 use: ["style-loader", "css-loader"]//用何种loader去处理test条件的文件,style会插入很多运行时代码 //css文件的内容会被转译成一个字符串,字符串在产物里作为样式代码 }] }
Webpack处理js——接入Babel
Babel是js代码转译工具,用于将es6转译成es5
- 安装依赖,
npm i -D @babel/core @babel/preset-env babel-loader - 声明产物出口output
- 执行
npx webpack
用@babel/preset-react处理jsx代码
用@babel/preset-typescript处理ts代码
module: {
rules: [{
test: /.js$/,
use: [{
loader: "babel-loader",
options: {
presets: [
['@babel/preset-env']
]
}
}]
}]
}
Webpack生成HTML
- 安装依赖
npm i -D html-webpack-plugin,用于自动生成HTML文件 - 声明产物出口,在配置里添加
plugins: [new HtmlWebpackPlugin()]
可以用Webpack自动化,无需自己写HTML。
可以通过HtmlWebpackPlugin的配置项配置HTML的标签和属性。
Webpack工具
- 开发效率类
- watch
- devtool
- devServer
- 性能优化
- cache
- performance
- 日志类
- stats
- infrastructureLogging
- 其他
- amd
- bail
HMR,Hot Module Replacement——模块热替换
写的代码能立刻更新到浏览器,而无需刷新。
启动Webpack时需要运行npx webpack serve
module.exports = {
...
devServer: {
hot:true
},
watch: true,
...
}
Tree-Shaking 树摇,删除死代码
对工具类库如Lodash有奇效,Lodash定义了很多工具函数,开启Tree-Shaking可以删掉没用到的代码。
删除的死代码:
- 没用到,不可达的代码
- 代码执行结果不会被用到
- 代码只读不写
module.exports = {
...
mode: "production",
optimization: {
usedExports: true
},
...
}
三、实践练习例子
配置文件例子
const path = require("path");
module.exports = {
entry: ".src/index",//定义当前项目的入口
mode: "development",
devtool: false,
output: {//项目打包完放到哪里
filename: "[name].js",
path: path.join(__dirname, "./dist")
},
module: {
rules: [{
test: /\.css$/,//过滤条件,满足test规则的采用loader处理
use: ["style-loader", "css-loader"]//用何种loader去处理test条件的文件,style会插入很多运行时代码
//css文件的内容会被转译成一个字符串,字符串在产物里作为样式代码
}]
}
};
四、课后个人总结
本节课学习了Webpack的背景,功能以及使用方法,了解到随着前端技术的发展,资源和项目管理方式不统一,带来了很多困难,Webpack的提出很好地解决了前端项目的模块化和一致化的问题。本节课还就流程类和工具类2个方面学习了Webpack的配置方法,由于Webpack的配置极为复杂,之后仍需大量的学习研究。
五、参考链接
Webpack 知识体系.pptx - 飞书云文档 (feishu.cn)
web前端之Less的详解_@逆风boy的博客-CSDN博客_前端less
前端基础学习之Sass_前端sass_哈哈ha~的博客-CSDN博客
深入浅出 Webpack · 深入浅出 Webpack (wuhaolin.cn)
Tecvan-fe/awesome-webpack-4plus (github.com)