[TOC] #### 1. webpack 介绍 --- webpack 官网: [https://webpack.js.org](https://webpack.js.org) **一、webpack 是什么?** webpack 是当前市场上最流行的打包工具 webpack 是代码编译工具,webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具,俗称: 打包工具 **二、为什么需要打包工具?** 开发时,我们会使用框架(Vue、React),ES6 模块化语法,Less/Sass 等 css 预处理器等语法进行开发。这样的代码浏览器是不能识别的,要想在浏览器运行必须经过编译,变成浏览器能识别的 JS、CSS 等语法,才能正常运行。 所以,我们需要打包工具帮我们完成这件事,除此之外,打包工具还能压缩代码、做兼容性处理,提升代码性能等 #### 2. webpack 基本使用 --- 构建 JS 模块化语法 ``` ├── public │ └── index.html └── src ├── js │ └── utils.js └── main.js ``` src/js/utils.js ```javascript export const sum = (...args) => { return args.reduce((sum, item) => sum += item, 0) }; ``` src/main.js ```javascript import { sum } from './js/utils'; console.log(sum(1, 2, 3, 4, 5)); ``` 在 `public/index.html` 中引入 `src/main.js` ``` <script src="../dist/main.js"></script> ``` 初始化 npm 项目,安装 webpack 依赖,进行打包 ``` npm init -y npm i webpack webpack-cli -D npx webpack ./src/main.js --mode=development ``` #### 3. webpack 5大核心概念 --- Webpack 的配置是围绕 5 大核心概念展开的,这五个概念非常重要 **一、entry (入口)** 指示 Webpack 从哪个文件开始打包 **二、output (输出)** 指示 Webpack 打包完的文件输出到哪里去,以及如何命名等 **三、loader (加载器)** webpack 本身只能处理 js,json 等资源,其他资源(vue,css,scss)需要借助相应的 loader,Webpack 才能解析 **四、plugins (插件)** 扩展 Webpack 的功能 **五、mode (模式)** 开发模式 (development)、生产模式 (production) #### 4. webpack 配置文件 --- **创建配置文件,配置 entry 入口** 在项目根目录下新建文件: `webpack.config.js`,文件名称必须是这个,文件内容如下所示: ```javascript module.exports = { entry: "./src/main.js" }; ``` **output 输出** 以下配置示例中的 output 中 path 和 filename 是默认值 ```javascript // nodejs 核心模块,专门用来处理路径问题 const path = require("path") module.exports = { // 入口 entry: "./src/main.js", // 相对路径 // 输出 output: { // 输出路径 // __dirname 是 nodejs 的变量,代表当前文件所在目录 path: path.resolve(__dirname, 'dist'), // 绝对路径 // 文件名 filename: "main.js", } }; ``` #### 5. webpack 运行脚本 --- 修改 `package.json` 文件,添加一个运行脚本。懂得都懂,添加后就可以使用 `npm run build` 命令进行打包了 ``` "scripts": { "build": "webpack --mode=development" }, ```  #### 6. webpack 处理样式资源 --- ##### 一、处理 css 资源 --- 创建 `src/css/index.css` 文件,文件内容如下: ``` .box1 { width: 150px; height: 150px; color: red; font-size: 18px; background: lightgreen; } ``` 在 `src/main.js` 中导入 css 文件 ``` import "./css/index.css" ``` 执行打包命令,你就会看到以下错误提示。这是因为 webpack 默认无法处理 CSS 资源,需要安装并配置 css 加载器 ``` ERROR in ./src/css/index.css 1:0 Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders ``` 安装加载 css 资源所需的 loader【吐槽: webpack 官网这个坑货,给的安装命令中没有 style-loader】 ``` npm install css-loader style-loader -D ``` 修改 webpack.config.js 配置文件,检测 css 文件,使用 loader 进行处理 ```javascript module.exports = { // 加载器 module: { rules: [ // loader 配置 { // 只检测 .css 后缀的文件 test: /\.css$/i, // loader 的执行顺序: 从右到左 // css-loader 将 css 资源编译成 commonjs 的模块到 js 中 // style-loader 将 js 中的 css 通过创建 style 标签添加到 html 文件中生效 use: ["style-loader", "css-loader"], }, ], }, }; ``` ##### 二、处理 less 资源 --- 创建 `src/less/index.less` 文件,文件内容如下: ```less @color: purple; .less { width: 150px; height: 150px; color: @color; font-size: 20px; background: lightcoral; } ``` 在 `src/main.js` 中导入 less 文件 ``` import "./less/index.less" ``` 安装加载 less 资源所需的 loader ``` npm install less less-loader --save-dev ``` 修改 webpack.config.js ```javascript module.exports = { module: { rules: [ { test: /\.less$/i, use: [ // compiles Less to CSS "style-loader", "css-loader", "less-loader", ], }, ], }, }; ``` ##### 三、处理 scss 资源 --- 创建 `src/scss/index.sass` 文件,文件内容如下: ``` $color: blue body .sass width: 150px height: 150px color: $color font-size: 20px background: yellowgreen ``` 创建 `src/scss/index.scss` 文件,文件内容如下: ``` $color: black; body { .scss { width: 150px; height: 150px; color: $color; font-size: 20px; background: lightpink; } } ``` 在 `src/main.js` 中导入 sass 和 scss 文件 ``` import "./scss/index.sass" import "./scss/index.scss" ``` 安装 `sass-loader` ``` npm install sass-loader sass --save-dev ``` 修改 webpack.config.js ``` module.exports = { module: { rules: [ { test: /\.s[ac]ss$/i, use: [ // Creates `style` nodes from JS strings "style-loader", // Translates CSS into CommonJS "css-loader", // Compiles Sass to CSS "sass-loader", ], }, ], }, }; ``` ##### 四、处理 stylus 资源 --- 创建 `src/stylus/index.styl` 文件,文件内容如下: ``` .stylus width 150px height 150px color white font-size 20px background #000 ``` 在 `src/main.js` 中导入 styl 文件 ``` import "./stylus/index.styl" ``` 安装 `stylus-loader` ``` npm install stylus stylus-loader --save-dev ``` 修改 webpack.config.js ``` module.exports = { module: { rules: [ { test: /\.styl$/, use: [ "style-loader", "css-loader", "stylus-loader", // compiles Styl to CSS ] }, ], }, }; ``` #### 7. webpack 处理图片资源 --- 过去在 webpack4 时,处理图片资源通过 `file-loader` 和 `url-loader` 进行处理。`file-loader` 的作用是将图片资源原封不动的输出,它会将资源处理为 webpack 能处理的资源, `url-loader` 的作用是将图片小于某个大小时处理为 base64 格式 而现在 webpack 5 已经将这两个 `Loader` 功能内置到 webpack 中了,我们只需要简单配置即可处理图片资源 --- **为什么要将体积比较小的图片转为 base64 格式 ?** 首先,要了解这个事情: 当图片转为 base64 后,得到的是一段很长的字符串,而且图片本身越大,得到的字符串和图片本身的差距越大。比如,当图片 5 KB 时,转为 base64 后约为 7 KB,体积只变大了 2 KB,但如果是 100 KB 的图片,转为 base64 后体积可能变为了 130 KB,此时体积变大了 30 KB。图片转为 base64 会增大体积,为什么还要将图片转为 base64 呢 ? 图片转为 base64 格式的利与弊 图片转为 base64 后可以减少网页的 http 请求,进而减少页面加载时间。但是 base64 格式编码内容太长,对于比较大的图片,并不适合使用,这样虽然减少了网页的 http 请求,但极大的增加了页面加载资源的大小,得不偿失了。 --- **前戏说完了,下面来正式处理图片资源** 首先,准备几张图片。挑选 1 张体积比较小的图片,2 张体积比较大的图片,下面是我准备的图片:  在前面写的样式资源中使用图片资源,比如: 作为背景图使用 增加以下两个 css 属性 ``` background-image: url('../images/1.jpg'); background-size: cover; ``` `src/css/index.css` 修改后 ``` .box1 { width: 150px; height: 150px; color: red; font-size: 18px; background: lightgreen; background-image: url('../images/1.jpg'); background-size: cover; } ``` `src/less/index.less` 修改后 ``` @color: purple; .less { width: 150px; height: 150px; color: @color; font-size: 20px; background: lightcoral; background-image: url('../images/2.png'); background-size: cover; } ``` `src/scss/index.sass` 修改后 ``` $color: blue body .sass width: 150px height: 150px color: $color font-size: 20px background: yellowgreen background-image: url('../images/3.webp') background-size: cover ``` 因为 webpack 已经内置处理图片资源的 loader,所以不需要安装 loader,直接执行打包命令即可。但是,默认不会将图片转为 base64 格式的,要使用这个转换,需要配置 loader。 查找官方文档找到配置: [https://webpack.js.org/guides/asset-modules/#root](https://webpack.js.org/guides/asset-modules/#root) 。该文档地址搜索方式,如下图所示:  通过查找官方文档,可在 webpack.config.js 中添加以下配置项。小于 5 KB 的图片转为 base64 格式 ```javascript module.exports = { module: { rules: [ { test: /\.(png|jpe?g|gif|webp|svg)$/i, type: 'asset', parser: { dataUrlCondition: { maxSize: 5 * 1024 // 5KB } } }, ] }, } ``` #### 8. webpack 文件输出目录配置 --- 配置方法直接看以下代码即可,就是修改 `output.filename`,以及处理图片资源 loader 中的 `generator.filename` ```javascript const path = require("path") module.exports = { // 输出 output: { // path 打包输出的文件根目录路径 path: path.resolve(__dirname, 'dist'), // filename 入口文件打包输出的文件名 filename: "static/js/main.js", }, // 加载器 module: { rules: [ { test: /\.(png|jpe?g|gif|webp|svg)$/i, type: 'asset', generator: { // 输出图片名称(图片名称默认20位字符) filename: 'static/images/[hash][ext][query]' // [hash:10] 图片名称取 hash 值前10位字符 // filename: 'static/images/[hash:10][ext][query]' }, } ] } } ``` #### 9. webpack 自动清空上次打包文件 --- 在 webpack4 中打包时想要自动清空上次打包文件需要安装插件实现,在 webpack5 中加个 `clean: true` 配置项即可 原理: 在打包前,先将 path 整个目录内容清空,再进行打包 ```javascript const path = require("path") module.exports = { output: { path: path.resolve(__dirname, 'dist'), filename: "static/js/main.js", clean: true // 自动清空上次打包文件 }, } ```