这是我参与「第四届青训营 」笔记创作活动的第18天。
笔记小结: 通过本节课的学习了有关Webpack的基本知识,包含其应用范围及打包的核心流程。本课程的内容较多,知识点较复杂,我将把本门课程的内容分两篇进行阐述,本篇是基础篇,重点在于灵活应用。现对照课程内容顺序将笔记补充如下。
01. 什么是Webpack
Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。 从图中我们可以看出,Webpack 可以将多种静态资源 js、css、less 转换成一个静态文件,减少了页面的请求。
前端项目由什么构成? —— 资源
旧时代手动管理这些资源,但有以下几个对开发效率影响非常大的缺点:
- 依赖手工,比如有50个JS文件……操作过程繁琐
- 当代码文件之间有依赖的时候,就得严格按依赖顺序书写
- 开发与生产环境一致,难以接入TS或JS新特性
- 比较难接入Less、Sass等工具
- JS、 图片、CSS资源管理模型不一致
后来,出现了很多前端工程化工具,特别是Webpack
Web本质上是一种前端资源编译、打包工具
- 多份资源文件打包成一个Bundle
- 支持
- Babel、Eslint、 TS、 CoffeScript、Less、 Sass
- 支持模块化处理css、图片等资源文件
- 支持 HMR + 开发服务器
- 支持持续监听、持续构建
- 支持代码分离
- 支持 Tree-shaking
- 支持 Sourcemap
- …
02. 使用Webpack
示例
- 安装(注意用管理员权限打开命令行)
npm i -D webpack webpack-cli
- 编辑配置文件webpack.config.js
module.exports = {
entry: 'main.js', // 定义当前项目的入口文件
output: { // 定义当前项目的输出文件
filename: "[name].js",
path: path.join(__dirname, "./dist"),
},
module: {// 定义一些loader相关的内容,可在下文看到
rules: [{
test: /\.less$/i,
use: ['style-loader', 'css-loader', 'less-loader']
}]
}
}
- 编辑配置文件webpack.config.js
module.exports = {
entry: 'main.js', // 定义当前项目的入口文件
output: { // 定义当前项目的输出文件
filename: "[name].js",
path: path.join(__dirname, "./dist"),
},
module: {// 定义一些loader相关的内容,可在下文看到
rules: [{
test: /\.less$/i,
use: ['style-loader', 'css-loader', 'less-loader']
}]
}
}
- 执行编译命令
npx webpack
步骤
Entry => Dependencies Lookup => Transform => Bundle => Output
极度简化版:
- 从entry中的入口文件开始启动编译
- 依赖解析:根据
require或者import等语句找到以来资源 - 根据
module配置,调用资源转移器将非JS资源编译为JS内容,直至所有资源处理完毕 - 资源合并打包:将转译后的资源内容合并打包为可直接在浏览器运行的JS文件
模块化 + 一致性
- 多个文件资源合并成一个,减少http请求数
- 支持模块化开发
- 支持高级JS特性
- 支持Typescript、 CoffeeScript 方言
- 统一图片、CSS、字体等其它资源的处理模型
- Etc…
关键配置项(如何使用?)
关于Webpack的使用方法,基本都围绕 配置 展开,而这些配置大致可划分为两类:
- 流程类:作用于流程中某个or若干个环节,直接影响打包效果的配置项
- 工具类:主流程之外,提供更多工程化能力的配置项
流程类配置总览:
配置总览:
按使用频率,主要有以下几大配置项
- entry/output——程序输入输出,必需的
- module/plugins
- mode
- watch/devServer/devtool
处理CSS
- 安装Loader
npm add -D css- Loader style-loader
- 添加module处理css文件
思考题
-
Loader有什么作用?为什么这里需要用到css-loader、style-loader
-
与旧时代,在HTML文件中维护CSS 相比,这种方式会有什么优劣处?
-
有没有接触过Less、Sass、 Stylus 这一类CSS预编译框架?如何在Webpack接入这些工具?
- 答:接触过less
-
参考资料:
-
Css-loader
-
Webpack 原理系列七:如何编写loader
-
Style-loader
-
接入Babel
- 安装依赖
npm -D @babel/core @babel/preset-env babel-loader
-
声明入口
entry& 产物出口output -
添加module处理css文件
module:{
rules:[
{
test:/\.js?$/,
use:[{
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env'
]
]
}
}]
}
]}
- 执行
npx webpack
思考题
- Babel具体有什么功能
- Babel与Webpack分别解决了什么问题?为何两者能协作到一起了?
参考资料:
生成html
- 安装依赖
npm i -D html-webpack-plugin
- 配置
const path = require( ”path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: "./src/index",
output: {
filename:“ [name]. js",
path: path.join(__dirname, "./dist"),
},
plugins: [new HtmlWebpackPlugin()]
};
- 执行
npx webpack
思考题
- 相比于手工维护HTML内容,这种自动生成的方式有什么优缺点?
参考资料:
HMR
Hot Module Replacement——模块热替换、
- 开启HMR
module.exports={
// ...
devServer: {
hot:true; // 必需
}
};
- 启动webpack
原理可参考:Webpack 原理系列十:HMR 原理全解析 (qq.com)
Tree-Shaking
Tree-Shaking -树摇,用于删除Dead Code
Dead Code
- 代码没有被用到,不可到达
- 代码的执行结果不会被用到
- 代码只读不写
Tree-Shaking
- 模块导出了,但未被其他模块使用
开启步骤?
- mode: “production”
- optimization: {usedExports: true}
module.exports = {
entry: "./src/ index",
mode: "production",
devtool: false,
optimization: {
usedExports: true,
},
};
ps:对工具类库如Lodash有奇效,能大大减小产物体积
其他工具
- 缓存
- Sourcemap (前面的课程中有提过)
- 性能监控
- 日志
- 代码压缩
- 分包
- …
思考题
- 除上面提到的内容,还有哪些配置可划分为“流程类” 配置?
- 工具类配置具体有什么作用?包括 devtool/cache/stat 等
补充:《Webpack 知识体系》进阶篇的内容将在下一篇文章中进行补充。