[TOC] #### 1. webpack 介紹 --- webpack 官網(wǎng): [https://webpack.js.org](https://webpack.js.org) **一、webpack 是什么?** webpack 是當(dāng)前市場上最流行的打包工具 webpack 是代碼編譯工具,webpack 是一個(gè)用于現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包工具,俗稱: 打包工具 **二、為什么需要打包工具?** 開發(fā)時(shí),我們會使用框架(Vue、React),ES6 模塊化語法,Less/Sass 等 css 預(yù)處理器等語法進(jìn)行開發(fā)。這樣的代碼瀏覽器是不能識別的,要想在瀏覽器運(yùn)行必須經(jīng)過編譯,變成瀏覽器能識別的 JS、CSS 等語法,才能正常運(yùn)行。 所以,我們需要打包工具幫我們完成這件事,除此之外,打包工具還能壓縮代碼、做兼容性處理,提升代碼性能等 #### 2. webpack 基本使用 --- 構(gòu)建 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 項(xiàng)目,安裝 webpack 依賴,進(jìn)行打包 ``` npm init -y npm i webpack webpack-cli -D npx webpack ./src/main.js --mode=development ``` #### 3. webpack 5大核心概念 --- Webpack 的配置是圍繞 5 大核心概念展開的,這五個(gè)概念非常重要 **一、entry (入口)** 指示 Webpack 從哪個(gè)文件開始打包 **二、output (輸出)** 指示 Webpack 打包完的文件輸出到哪里去,以及如何命名等 **三、loader (加載器)** webpack 本身只能處理 js,json 等資源,其他資源(vue,css,scss)需要借助相應(yīng)的 loader,Webpack 才能解析 **四、plugins (插件)** 擴(kuò)展 Webpack 的功能 **五、mode (模式)** 開發(fā)模式 (development)、生產(chǎn)模式 (production) #### 4. webpack 配置文件 --- **創(chuàng)建配置文件,配置 entry 入口** 在項(xiàng)目根目錄下新建文件: `webpack.config.js`,文件名稱必須是這個(gè),文件內(nèi)容如下所示: ```javascript module.exports = { entry: "./src/main.js" }; ``` **output 輸出** 以下配置示例中的 output 中 path 和 filename 是默認(rèn)值 ```javascript // nodejs 核心模塊,專門用來處理路徑問題 const path = require("path") module.exports = { // 入口 entry: "./src/main.js", // 相對路徑 // 輸出 output: { // 輸出路徑 // __dirname 是 nodejs 的變量,代表當(dāng)前文件所在目錄 path: path.resolve(__dirname, 'dist'), // 絕對路徑 // 文件名 filename: "main.js", } }; ``` #### 5. webpack 運(yùn)行腳本 --- 修改 `package.json` 文件,添加一個(gè)運(yùn)行腳本。懂得都懂,添加后就可以使用 `npm run build` 命令進(jìn)行打包了 ``` "scripts": { "build": "webpack --mode=development" }, ``` ![](https://img.itqaq.com/art/content/f307015eabd1e72b5713339fab5c0127.png) #### 6. webpack 處理樣式資源 --- ##### 一、處理 css 資源 --- 創(chuàng)建 `src/css/index.css` 文件,文件內(nèi)容如下: ``` .box1 { width: 150px; height: 150px; color: red; font-size: 18px; background: lightgreen; } ``` 在 `src/main.js` 中導(dǎo)入 css 文件 ``` import "./css/index.css" ``` 執(zhí)行打包命令,你就會看到以下錯(cuò)誤提示。這是因?yàn)?webpack 默認(rèn)無法處理 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 官網(wǎng)這個(gè)坑貨,給的安裝命令中沒有 style-loader】 ``` npm install css-loader style-loader -D ``` 修改 webpack.config.js 配置文件,檢測 css 文件,使用 loader 進(jìn)行處理 ```javascript module.exports = { // 加載器 module: { rules: [ // loader 配置 { // 只檢測 .css 后綴的文件 test: /\.css$/i, // loader 的執(zhí)行順序: 從右到左 // css-loader 將 css 資源編譯成 commonjs 的模塊到 js 中 // style-loader 將 js 中的 css 通過創(chuàng)建 style 標(biāo)簽添加到 html 文件中生效 use: ["style-loader", "css-loader"], }, ], }, }; ``` ##### 二、處理 less 資源 --- 創(chuàng)建 `src/less/index.less` 文件,文件內(nèi)容如下: ```less @color: purple; .less { width: 150px; height: 150px; color: @color; font-size: 20px; background: lightcoral; } ``` 在 `src/main.js` 中導(dǎo)入 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 資源 --- 創(chuàng)建 `src/scss/index.sass` 文件,文件內(nèi)容如下: ``` $color: blue body .sass width: 150px height: 150px color: $color font-size: 20px background: yellowgreen ``` 創(chuàng)建 `src/scss/index.scss` 文件,文件內(nèi)容如下: ``` $color: black; body { .scss { width: 150px; height: 150px; color: $color; font-size: 20px; background: lightpink; } } ``` 在 `src/main.js` 中導(dǎo)入 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 資源 --- 創(chuàng)建 `src/stylus/index.styl` 文件,文件內(nèi)容如下: ``` .stylus width 150px height 150px color white font-size 20px background #000 ``` 在 `src/main.js` 中導(dǎo)入 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 時(shí),處理圖片資源通過 `file-loader` 和 `url-loader` 進(jìn)行處理。`file-loader` 的作用是將圖片資源原封不動(dòng)的輸出,它會將資源處理為 webpack 能處理的資源, `url-loader` 的作用是將圖片小于某個(gè)大小時(shí)處理為 base64 格式 而現(xiàn)在 webpack 5 已經(jīng)將這兩個(gè) `Loader` 功能內(nèi)置到 webpack 中了,我們只需要簡單配置即可處理圖片資源 --- **為什么要將體積比較小的圖片轉(zhuǎn)為 base64 格式 ?** 首先,要了解這個(gè)事情: 當(dāng)圖片轉(zhuǎn)為 base64 后,得到的是一段很長的字符串,而且圖片本身越大,得到的字符串和圖片本身的差距越大。比如,當(dāng)圖片 5 KB 時(shí),轉(zhuǎn)為 base64 后約為 7 KB,體積只變大了 2 KB,但如果是 100 KB 的圖片,轉(zhuǎn)為 base64 后體積可能變?yōu)榱?130 KB,此時(shí)體積變大了 30 KB。圖片轉(zhuǎn)為 base64 會增大體積,為什么還要將圖片轉(zhuǎn)為 base64 呢 ? 圖片轉(zhuǎn)為 base64 格式的利與弊 圖片轉(zhuǎn)為 base64 后可以減少網(wǎng)頁的 http 請求,進(jìn)而減少頁面加載時(shí)間。但是 base64 格式編碼內(nèi)容太長,對于比較大的圖片,并不適合使用,這樣雖然減少了網(wǎng)頁的 http 請求,但極大的增加了頁面加載資源的大小,得不償失了。 --- **前戲說完了,下面來正式處理圖片資源** 首先,準(zhǔn)備幾張圖片。挑選 1 張?bào)w積比較小的圖片,2 張?bào)w積比較大的圖片,下面是我準(zhǔn)備的圖片: ![](https://img.itqaq.com/art/content/9101deb7bfd95bf5d362a1977770a3bc.png) 在前面寫的樣式資源中使用圖片資源,比如: 作為背景圖使用 增加以下兩個(gè) 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 ``` 因?yàn)?webpack 已經(jīng)內(nèi)置處理圖片資源的 loader,所以不需要安裝 loader,直接執(zhí)行打包命令即可。但是,默認(rèn)不會將圖片轉(zhuǎn)為 base64 格式的,要使用這個(gè)轉(zhuǎn)換,需要配置 loader。 查找官方文檔找到配置: [https://webpack.js.org/guides/asset-modules/#root](https://webpack.js.org/guides/asset-modules/#root) 。該文檔地址搜索方式,如下圖所示: ![](https://img.itqaq.com/art/content/4d78b4d3f74675ec3ddc49cb0ad37e3f.png) 通過查找官方文檔,可在 webpack.config.js 中添加以下配置項(xiàng)。小于 5 KB 的圖片轉(zhuǎn)為 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: { // 輸出圖片名稱(圖片名稱默認(rèn)20位字符) filename: 'static/images/[hash][ext][query]' // [hash:10] 圖片名稱取 hash 值前10位字符 // filename: 'static/images/[hash:10][ext][query]' }, } ] } } ``` #### 9. webpack 自動(dòng)清空上次打包文件 --- 在 webpack4 中打包時(shí)想要自動(dòng)清空上次打包文件需要安裝插件實(shí)現(xiàn),在 webpack5 中加個(gè) `clean: true` 配置項(xiàng)即可 原理: 在打包前,先將 path 整個(gè)目錄內(nèi)容清空,再進(jìn)行打包 ```javascript const path = require("path") module.exports = { output: { path: path.resolve(__dirname, 'dist'), filename: "static/js/main.js", clean: true // 自動(dòng)清空上次打包文件 }, } ```