前言
为什么需要打包工具?
开发时,我们会使用框架(React、Vue),ES6 模块化语法,Less/Sass 等 css 预处理器等语法进行开发。
这样的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、Css 等语法,才能运行。
所以我们需要打包工具帮我们做完这些事。
除此之外,打包工具还能压缩代码、做兼容性处理、提升代码性能等。
有哪些打包工具?
- Grunt
- Gulp
- Parcel
- Webpack
- Rollup
- Vite
- …
目前市面上最流量的是 Webpack,所以我们主要以 Webpack 来介绍使用打包工具
基本使用
Webpack
是一个静态资源打包工具。
它会以一个或多个文件作为打包的入口,将我们整个项目所有文件编译组合成一个或多个文件输出出去。
输出的文件就是编译好的文件,就可以在浏览器段运行了。
我们将 Webpack
输出的文件叫做 bundle
。
功能介绍
Webpack 本身功能是有限的:
- 开发模式:仅能编译 JS 中的
ES Module
语法 - 生产模式:能编译 JS 中的
ES Module
语法,还能压缩 JS 代码
开始使用
1. 资源目录
1 2 3 4 5 6
| webpack_code └── src ├── js │ ├── count.js │ └── sum.js └── main.js
|
2. 创建文件
1 2 3
| export default function count(x, y) { return x - y; }
|
1 2 3
| export default function sum(...args) { return args.reduce((p, c) => p + c, 0); }
|
1 2 3 4 5
| import count from "./js/count"; import sum from "./js/sum";
console.log(count(2, 1)); console.log(sum(1, 2, 3, 4));
|
3. 下载依赖
打开终端,来到项目根目录。运行以下指令:
此时会生成一个基础的 package.json
文件。
需要注意的是 package.json
中 name
字段不能叫做 webpack
, 否则下一步会报错
1
| npm i webpack webpack-cli -D
|
4. 启用 Webpack
1
| npx webpack ./src/main.js --mode=development
|
1
| npx webpack ./src/main.js --mode=production
|
npx webpack
: 是用来运行本地安装 Webpack
包的。
./src/main.js
: 指定 Webpack
从 main.js
文件开始打包,不但会打包 main.js
,还会将其依赖也一起打包进来。
--mode=xxx
:指定模式(环境)。
5. 观察输出文件
默认 Webpack
会将文件打包输出到 dist
目录下,我们查看 dist
目录下文件情况就好了
小结
Webpack
本身功能比较少,只能处理 js
资源,一旦遇到 css
等其他资源就会报错。
所以我们学习 Webpack
,就是主要学习如何处理其他资源。
基本配置
在开始使用 Webpack
之前,我们需要对 Webpack
的配置有一定的认识。
5 大核心概念
准备 Webpack 配置文件
在项目根目录下新建文件:webpack.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| module.exports = { entry: "", output: {}, module: { rules: [], }, plugins: [], mode: "", };
|
Webpack 是基于 Node.js 运行的,所以采用 Common.js
模块化规范
修改配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "main.js", }, module: { rules: [], }, plugins: [], mode: "development", };
|
此时功能和之前一样,也不能处理样式资源。
小结
Webpack 将来都通过 webpack.config.js
文件进行配置,来增强 Webpack 的功能
我们后面会以两个模式来分别搭建 Webpack 的配置,先进行开发模式,再完成生产模式
开发模式介绍
开发模式顾名思义就是我们开发代码时使用的模式。
这个模式下我们主要做两件事:
处理样式资源
本章节我们学习使用 Webpack 如何处理 Css、Less、Sass、Scss、Styl 样式资源
介绍
Webpack 本身是不能识别样式资源的,所以我们需要借助 Loader 来帮助 Webpack 解析样式资源
我们找 Loader 都应该去官方文档中找到对应的 Loader,然后使用
官方文档找不到的话,可以从社区 Github 中搜索查询
Webpack 官方 Loader 文档
处理 Css 资源
1. 下载包
1
| npm i css-loader style-loader -D
|
注意:需要下载两个 loader
2. 功能介绍
css-loader
:负责将 Css 文件编译成 Webpack 能识别的模块style-loader
:会动态创建一个 Style 标签,里面放置 Webpack 中 Css 模块内容
此时样式就会以 Style 标签的形式在页面上生效
3. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "main.js", }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, ], }, plugins: [], mode: "development", };
|
4. 添加 Css 资源
1 2 3 4 5
| .box1 { width: 100px; height: 100px; background-color: pink; }
|
1 2 3 4 5 6 7
| import count from "./js/count"; import sum from "./js/sum";
import "./css/index.css";
console.log(count(2, 1)); console.log(sum(1, 2, 3, 4));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>webpack5</title> </head> <body> <h1>Hello Webpack5</h1> <div class="box1"></div> <script src="../dist/main.js"></script> </body> </html>
|
5. 运行指令
打开 index.html 页面查看效果
处理 Less 资源
1. 下载包
2. 功能介绍
less-loader
:负责将 Less 文件编译成 Css 文件
3. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "main.js", }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, ], }, plugins: [], mode: "development", };
|
4. 添加 Less 资源
1 2 3 4 5
| .box2 { width: 100px; height: 100px; background-color: deeppink; }
|
1 2 3 4 5 6 7 8
| import count from "./js/count"; import sum from "./js/sum";
import "./css/index.css"; import "./less/index.less";
console.log(count(2, 1)); console.log(sum(1, 2, 3, 4));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>webpack5</title> </head> <body> <h1>Hello Webpack5</h1> <div class="box1"></div> <div class="box2"></div> <script src="../dist/main.js"></script> </body> </html>
|
5. 运行指令
打开 index.html 页面查看效果
处理 Sass 和 Scss 资源
1. 下载包
1
| npm i sass-loader sass -D
|
注意:需要下载两个
2. 功能介绍
sass-loader
:负责将 Sass 文件编译成 css 文件sass
:sass-loader
依赖 sass
进行编译
3. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "main.js", }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, ], }, plugins: [], mode: "development", };
|
4. 添加 Sass 资源
1 2 3 4 5
| .box3 width: 100px height: 100px background-color: hotpink
|
1 2 3 4 5
| .box4 { width: 100px; height: 100px; background-color: lightpink; }
|
1 2 3 4 5 6 7 8 9 10
| import count from "./js/count"; import sum from "./js/sum";
import "./css/index.css"; import "./less/index.less"; import "./sass/index.sass"; import "./sass/index.scss";
console.log(count(2, 1)); console.log(sum(1, 2, 3, 4));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>webpack5</title> </head> <body> <h1>Hello Webpack5</h1> <div class="box1"></div> <div class="box2"></div> <div class="box3"></div> <div class="box4"></div> <script src="../dist/main.js"></script> </body> </html>
|
5. 运行指令
打开 index.html 页面查看效果
处理 Styl 资源
1. 下载包
1
| npm i stylus-loader stylus -D
|
2. 功能介绍
stylus-loader
:负责将 Styl 文件编译成 Css 文件
3. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "main.js", }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, ], }, plugins: [], mode: "development", };
|
4. 添加 Styl 资源
1 2 3 4 5
| .box width 100px height 100px background-color pink
|
1 2 3 4 5 6 7 8 9 10 11 12
| import { add } from "./math"; import count from "./js/count"; import sum from "./js/sum";
import "./css/index.css"; import "./less/index.less"; import "./sass/index.sass"; import "./sass/index.scss"; import "./styl/index.styl";
console.log(count(2, 1)); console.log(sum(1, 2, 3, 4));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>webpack5</title> </head> <body> <h1>Hello Webpack5</h1> <div class="box1"></div> <div class="box2"></div> <div class="box3"></div> <div class="box4"></div> <div class="box5"></div> <script src="../dist/main.js"></script> </body> </html>
|
5. 运行指令
打开 index.html 页面查看效果
处理图片资源
过去在 Webpack4 时,我们处理图片资源通过 file-loader
和 url-loader
进行处理
现在 Webpack5 已经将两个 Loader 功能内置到 Webpack 里了,我们只需要简单配置即可处理图片资源
1. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "main.js", }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", }, ], }, plugins: [], mode: "development", };
|
2. 添加图片资源
- src/images/1.jpeg
- src/images/2.png
- src/images/3.gif
3. 使用图片资源
1 2 3 4 5 6
| .box2 { width: 100px; height: 100px; background-image: url("../images/1.jpeg"); background-size: cover; }
|
1 2 3 4 5
| .box3 width: 100px height: 100px background-image: url("../images/2.png") background-size: cover
|
1 2 3 4 5
| .box5 width 100px height 100px background-image url("../images/3.gif") background-size cover
|
4. 运行指令
打开 index.html 页面查看效果
5. 输出资源情况
此时如果查看 dist 目录的话,会发现多了三张图片资源
因为 Webpack 会将所有打包好的资源输出到 dist 目录下
因为经过 style-loader
的处理,样式资源打包到 main.js 里面去了,所以没有额外输出出来
6. 对图片资源进行优化
将小于某个大小的图片转化成 data URI 形式(Base64 格式)
此时输出的图片文件就只有两张,有一张图片以 data URI 形式内置到 js 中了
(注意:需要将上次打包生成的文件清空,再重新打包才有效果)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "main.js", }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024 } } }, ], }, plugins: [], mode: "development", };
|
修改输出资源的名称和路径
1. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "static/js/main.js", }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, ], }, plugins: [], mode: "development", };
|
2. 修改 index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>webpack5</title> </head> <body> <h1>Hello Webpack5</h1> <div class="box1"></div> <div class="box2"></div> <div class="box3"></div> <div class="box4"></div> <div class="box5"></div> <script src="../dist/static/js/main.js"></script> </body> </html>
|
3. 运行指令
(注意:需要将上次打包生成的文件清空,再重新打包才有效果)
1 2 3 4 5 6
| ├── dist └── static ├── imgs │ └── 7003350e.png └── js └── main.js
|
自动清空上次打包资源
1. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 40 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, ], }, plugins: [], mode: "development", };
|
2. 运行指令
观察 dist 目录资源情况
处理字体图标资源
1. 下载字体图标文件
打开阿里巴巴矢量图标库
选择想要的图标添加到购物车,统一下载到本地
2. 添加字体图标资源
src/fonts/iconfont.ttf
src/fonts/iconfont.woff
src/fonts/iconfont.woff2
src/css/iconfont.css
src/main.js
1 2 3 4 5 6 7 8 9 10 11 12 13
| import { add } from "./math"; import count from "./js/count"; import sum from "./js/sum";
import "./css/iconfont.css"; import "./css/index.css"; import "./less/index.less"; import "./sass/index.sass"; import "./sass/index.scss"; import "./styl/index.styl";
console.log(count(2, 1)); console.log(sum(1, 2, 3, 4));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>webpack5</title> </head> <body> <h1>Hello Webpack5</h1> <div class="box1"></div> <div class="box2"></div> <div class="box3"></div> <div class="box4"></div> <div class="box5"></div> <i class="iconfont icon-arrow-down"></i> <i class="iconfont icon-ashbin"></i> <i class="iconfont icon-browse"></i> <script src="../dist/static/js/main.js"></script> </body> </html>
|
3. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, ], }, plugins: [], mode: "development", };
|
type: "asset/resource"
和type: "asset"
的区别:
type: "asset/resource"
相当于file-loader
, 将文件转化成 Webpack 能识别的资源,其他不做处理type: "asset"
相当于url-loader
, 将文件转化成 Webpack 能识别的资源,同时小于某个大小的资源会处理成 data URI 形式
4. 运行指令
打开 index.html 页面查看效果
处理其他资源
开发中可能还存在一些其他资源,如音视频等,我们也一起处理了
1. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| const path = require("path");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?|map4|map3|avi)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, ], }, plugins: [], mode: "development", };
|
就是在处理字体图标资源基础上增加其他文件类型,统一处理即可
2. 运行指令
打开 index.html 页面查看效果
处理 js 资源
有人可能会问,js 资源 Webpack 不能已经处理了吗,为什么我们还要处理呢?
原因是 Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法,不能编译其他语法,导致 js 不能在 IE 等浏览器运行,所以我们希望做一些兼容性处理。
其次开发中,团队对代码格式是有严格要求的,我们不能由肉眼去检测代码格式,需要使用专业的工具来检测。
- 针对 js 兼容性处理,我们使用
Babel
来完成 - 针对代码格式,我们使用
Eslint
来完成
我们先完成 Eslint,检测代码格式无误后,在由 Babel 做代码兼容性处理。
Eslint
可组装的JavaScript
和JSX
检查工具。
这句话意思就是:它是用来检测 js 和 jsx 语法的工具,可以配置各项功能。
我们使用 Eslint,关键是写 Eslint 配置文件,里面写上各种 rules 规则,将来运行 Eslint 时就会以写的规则对代码进行检查。
1. 配置文件
配置文件由很多种写法:
.eslintrc.*
:新建文件,位于项目根目录.eslintrc
.eslintrc.js
.eslintrc.json
- 区别在于配置格式不一样
package.json
中 eslintConfig
:不需要创建文件,在原有文件基础上写
ESLint 会查找和自动读取它们,所以以上配置文件只需要存在一个即可
2. 具体配置
我们以 .eslintrc.js
配置文件为例:
1 2 3 4 5 6 7 8 9 10
| module.exports = { parserOptions: {}, rules: {}, extends: [], };
|
- parserOptions 解析选项
1 2 3 4 5 6 7
| parserOptions: { ecmaVersion: 6, sourceType: "module", ecmaFeatures: { jsx: true } }
|
- rules 具体规则
"off"
或 0
- 关闭规则"warn"
或 1
- 开启规则,使用警告级别的错误:warn
(不会导致程序退出)"error"
或 2
- 开启规则,使用错误级别的错误:error
(当被触发的时候,程序会退出)
1 2 3 4 5 6 7 8 9 10 11 12
| rules: { semi: "error", 'array-callback-return': 'warn', 'default-case': [ 'warn', { commentPattern: '^no default$' } ], eqeqeq: [ 'warn', 'smart' ], }
|
更多规则详见:规则文档
- extends 继承
开发中一点点写 rules 规则太费劲了,所以有更好的办法,继承现有的规则。
现有以下较为有名的规则:
1 2 3 4 5 6 7 8 9
| module.exports = { extends: ["react-app"], rules: { eqeqeq: ["warn", "smart"], }, };
|
3. 在 Webpack 中使用
- 下载包
1
| npm i eslint-webpack-plugin eslint -D
|
- 定义 Eslint 配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| module.exports = { extends: ["eslint:recommended"], env: { node: true, browser: true, }, parserOptions: { ecmaVersion: 6, sourceType: "module", }, rules: { "no-var": 2, }, };
|
- 修改 js 文件代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import count from "./js/count"; import sum from "./js/sum";
import "./css/iconfont.css"; import "./css/index.css"; import "./less/index.less"; import "./sass/index.sass"; import "./sass/index.scss"; import "./styl/index.styl";
var result1 = count(2, 1); console.log(result1); var result2 = sum(1, 2, 3, 4); console.log(result2);
|
- 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| const path = require("path"); const ESLintWebpackPlugin = require("eslint-webpack-plugin");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, ], }, plugins: [ new ESLintWebpackPlugin({ context: path.resolve(__dirname, "src"), }), ], mode: "development", };
|
- 运行指令
在控制台查看 Eslint 检查效果
4. VSCode Eslint 插件
打开 VSCode,下载 Eslint 插件,即可不用编译就能看到错误,可以提前解决
但是此时就会对项目所有文件默认进行 Eslint 检查了,我们 dist 目录下的打包后文件就会报错。但是我们只需要检查 src 下面的文件,不需要检查 dist 下面的文件。
所以可以使用 Eslint 忽略文件解决。在项目根目录新建下面文件:
Babel
JavaScript 编译器。
主要用于将 ES6 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中
1. 配置文件
配置文件由很多种写法:
babel.config.*
:新建文件,位于项目根目录babel.config.js
babel.config.json
.babelrc.*
:新建文件,位于项目根目录.babelrc
.babelrc.js
.babelrc.json
package.json
中 babel
:不需要创建文件,在原有文件基础上写
Babel 会查找和自动读取它们,所以以上配置文件只需要存在一个即可
2. 具体配置
我们以 babel.config.js
配置文件为例:
1 2 3 4
| module.exports = { presets: [], };
|
- presets 预设
简单理解:就是一组 Babel 插件, 扩展 Babel 功能
@babel/preset-env
: 一个智能预设,允许您使用最新的 JavaScript。@babel/preset-react
:一个用来编译 React jsx 语法的预设@babel/preset-typescript
:一个用来编译 TypeScript 语法的预设
3. 在 Webpack 中使用
- 下载包
1
| npm i babel-loader @babel/core @babel/preset-env -D
|
- 定义 Babel 配置文件
1 2 3
| module.exports = { presets: ["@babel/preset-env"], };
|
- 修改 js 文件代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import count from "./js/count"; import sum from "./js/sum";
import "./css/iconfont.css"; import "./css/index.css"; import "./less/index.less"; import "./sass/index.sass"; import "./sass/index.scss"; import "./styl/index.styl";
const result1 = count(2, 1); console.log(result1); const result2 = sum(1, 2, 3, 4); console.log(result2);
|
- 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| const path = require("path"); const ESLintWebpackPlugin = require("eslint-webpack-plugin");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", }, ], }, plugins: [ new ESLintWebpackPlugin({ context: path.resolve(__dirname, "src"), }), ], mode: "development", };
|
- 运行指令
打开打包后的 dist/static/js/main.js
文件查看,会发现箭头函数等 ES6 语法已经转换了
处理 Html 资源
1. 下载包
1
| npm i html-webpack-plugin -D
|
2. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| const path = require("path"); const ESLintWebpackPlugin = require("eslint-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", }, ], }, plugins: [ new ESLintWebpackPlugin({ context: path.resolve(__dirname, "src"), }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "public/index.html"), }), ], mode: "development", };
|
3. 修改 index.html
去掉引入的 js 文件,因为 HtmlWebpackPlugin 会自动引入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>webpack5</title> </head> <body> <h1>Hello Webpack5</h1> <div class="box1"></div> <div class="box2"></div> <div class="box3"></div> <div class="box4"></div> <div class="box5"></div> <i class="iconfont icon-arrow-down"></i> <i class="iconfont icon-ashbin"></i> <i class="iconfont icon-browse"></i> </body> </html>
|
4. 运行指令
此时 dist 目录就会输出一个 index.html 文件
开发服务器&自动化
每次写完代码都需要手动输入指令才能编译代码,太麻烦了,我们希望一切自动化
1. 下载包
1
| npm i webpack-dev-server -D
|
2. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| const path = require("path"); const ESLintWebpackPlugin = require("eslint-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", }, ], }, plugins: [ new ESLintWebpackPlugin({ context: path.resolve(__dirname, "src"), }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "public/index.html"), }), ], devServer: { host: "localhost", port: "3000", open: true, }, mode: "development", };
|
3. 运行指令
注意运行指令发生了变化
并且当你使用开发服务器时,所有代码都会在内存中编译打包,并不会输出到 dist 目录下。
开发时我们只关心代码能运行,有效果即可,至于代码被编译成什么样子,我们并不需要知道。
生产模式介绍
生产模式是开发完成代码后,我们需要得到代码将来部署上线。
这个模式下我们主要对代码进行优化,让其运行性能更好。
优化主要从两个角度出发:
- 优化代码运行性能
- 优化代码打包速度
生产模式准备
我们分别准备两个配置文件来放不同的配置
1. 文件目录
1 2 3 4 5 6 7 8 9 10 11 12
| ├── webpack-test (项目根目录) ├── config (Webpack配置文件目录) │ ├── webpack.dev.js(开发模式配置文件) │ └── webpack.prod.js(生产模式配置文件) ├── node_modules (下载包存放目录) ├── src (项目源码目录,除了html其他都在src里面) │ └── 略 ├── public (项目html文件) │ └── index.html ├── .eslintrc.js(Eslint配置文件) ├── babel.config.js(Babel配置文件) └── package.json (包的依赖管理配置文件)
|
2. 修改 webpack.dev.js
因为文件目录变了,所以所有绝对路径需要回退一层目录才能找到对应的文件。相对路径不需要处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| const path = require("path"); const ESLintWebpackPlugin = require("eslint-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = { entry: "./src/main.js", output: { path: undefined, filename: "static/js/main.js", }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", }, ], }, plugins: [ new ESLintWebpackPlugin({ context: path.resolve(__dirname, "../src"), }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "../public/index.html"), }), ], devServer: { host: "localhost", port: "3000", open: true, }, mode: "development", };
|
运行开发模式的指令:
1
| npx webpack serve --config ./config/webpack.dev.js
|
3. 修改 webpack.prod.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| const path = require("path"); const ESLintWebpackPlugin = require("eslint-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "../dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"], }, { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", }, ], }, plugins: [ new ESLintWebpackPlugin({ context: path.resolve(__dirname, "../src"), }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "../public/index.html"), }), ], mode: "production", };
|
运行生产模式的指令:
1
| npx webpack --config ./config/webpack.prod.js
|
4. 配置运行指令
为了方便运行不同模式的指令,我们将指令定义在 package.json 中 scripts 里面
1 2 3 4 5 6 7 8 9
| { "scripts": { "start": "npm run dev", "dev": "npx webpack serve --config ./config/webpack.dev.js", "build": "npx webpack --config ./config/webpack.prod.js" } }
|
以后启动指令:
- 开发模式:
npm start
或 npm run dev
- 生产模式:
npm run build
Css 处理
提取 Css 成单独文件
Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式
这样对于网站来说,会出现闪屏现象,用户体验不好
我们应该是单独的 Css 文件,通过 link 标签加载性能才好
1. 下载包
1
| npm i mini-css-extract-plugin -D
|
2. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| const path = require("path"); const ESLintWebpackPlugin = require("eslint-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "../dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.less$/, use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"], }, { test: /\.s[ac]ss$/, use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], }, { test: /\.styl$/, use: [MiniCssExtractPlugin.loader, "css-loader", "stylus-loader"], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", }, ], }, plugins: [ new ESLintWebpackPlugin({ context: path.resolve(__dirname, "../src"), }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "../public/index.html"), }), new MiniCssExtractPlugin({ filename: "static/css/main.css", }), ], mode: "production", };
|
3. 运行指令
Css 兼容性处理
1. 下载包
1
| npm i postcss-loader postcss postcss-preset-env -D
|
2. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| const path = require("path"); const ESLintWebpackPlugin = require("eslint-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "../dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: [ "postcss-preset-env", ], }, }, }, ], }, { test: /\.less$/, use: [ MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: [ "postcss-preset-env", ], }, }, }, "less-loader", ], }, { test: /\.s[ac]ss$/, use: [ MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: [ "postcss-preset-env", ], }, }, }, "sass-loader", ], }, { test: /\.styl$/, use: [ MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: [ "postcss-preset-env", ], }, }, }, "stylus-loader", ], }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", }, ], }, plugins: [ new ESLintWebpackPlugin({ context: path.resolve(__dirname, "../src"), }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "../public/index.html"), }), new MiniCssExtractPlugin({ filename: "static/css/main.css", }), ], mode: "production", };
|
3. 控制兼容性
我们可以在 package.json
文件中添加 browserslist
来控制样式的兼容性做到什么程度。
1 2 3 4
| { "browserslist": ["ie >= 8"] }
|
想要知道更多的 browserslist
配置,查看browserslist 文档
以上为了测试兼容性所以设置兼容浏览器 ie8 以上。
实际开发中我们一般不考虑旧版本浏览器了,所以我们可以这样设置:
1 2 3 4
| { "browserslist": ["last 2 version", "> 1%", "not dead"] }
|
4. 合并配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| const path = require("path"); const ESLintWebpackPlugin = require("eslint-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const getStyleLoaders = (preProcessor) => { return [ MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: [ "postcss-preset-env", ], }, }, }, preProcessor, ].filter(Boolean); };
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "../dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: getStyleLoaders(), }, { test: /\.less$/, use: getStyleLoaders("less-loader"), }, { test: /\.s[ac]ss$/, use: getStyleLoaders("sass-loader"), }, { test: /\.styl$/, use: getStyleLoaders("stylus-loader"), }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", }, ], }, plugins: [ new ESLintWebpackPlugin({ context: path.resolve(__dirname, "../src"), }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "../public/index.html"), }), new MiniCssExtractPlugin({ filename: "static/css/main.css", }), ], mode: "production", };
|
5. 运行指令
Css 压缩
1. 下载包
1
| npm i css-minimizer-webpack-plugin -D
|
2. 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| const path = require("path"); const ESLintWebpackPlugin = require("eslint-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const getStyleLoaders = (preProcessor) => { return [ MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: [ "postcss-preset-env", ], }, }, }, preProcessor, ].filter(Boolean); };
module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "../dist"), filename: "static/js/main.js", clean: true, }, module: { rules: [ { test: /\.css$/, use: getStyleLoaders(), }, { test: /\.less$/, use: getStyleLoaders("less-loader"), }, { test: /\.s[ac]ss$/, use: getStyleLoaders("sass-loader"), }, { test: /\.styl$/, use: getStyleLoaders("stylus-loader"), }, { test: /\.(png|jpe?g|gif|webp)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, generator: { filename: "static/imgs/[hash:8][ext][query]", }, }, { test: /\.(ttf|woff2?)$/, type: "asset/resource", generator: { filename: "static/media/[hash:8][ext][query]", }, }, { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", }, ], }, plugins: [ new ESLintWebpackPlugin({ context: path.resolve(__dirname, "../src"), }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "../public/index.html"), }), new MiniCssExtractPlugin({ filename: "static/css/main.css", }), new CssMinimizerPlugin(), ], mode: "production", };
|
3. 运行指令
html 压缩
默认生产模式已经开启了:html 压缩和 js 压缩
不需要额外进行配置
总结
本章节我们学会了 Webpack 基本使用,掌握了以下功能:
两种开发模式
开发模式:代码能编译自动化运行
生产模式:代码编译优化输出
Webpack 基本功能
Webpack 配置文件
5 个核心概念
- entry
- output
- loader
- plugins
- mode
devServer 配置
Webpack 脚本指令用法