日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一篇帶給你webpack優(yōu)秀實踐

前言

本文講述的最佳實踐是從日常業(yè)務(wù)中總結(jié)而出的,不一定適合所有項目。畢竟每個公司或個人的項目不同,最佳實踐也會有所不同。但是可以從這篇文章借鑒吸收一點有用的東西。

成都創(chuàng)新互聯(lián)公司2013年成立,先為臨沭等服務(wù)建站,臨沭等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為臨沭企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

為了避免出現(xiàn) 我這明明可以,你那怎么不行 的尷尬情況,這里列一下文章涉及到依賴的版本號。

 
 
 
 
  1. ├── webpack           5.39.1
  2. ├── webpack-cli       4.7.2
  3. ├── node              12.8.0
  4. ├── npm               6.10.2

正文

初始化項目

 
 
 
 
  1. 1. mkdir test-app && cd test-app
  2. 2. npm init

首先添加一個入口文件 /src/index.js 和 webpack 配置文件 webpack.config.js,現(xiàn)在我們的目錄結(jié)構(gòu)如下

 
 
 
 
  1. test-app
  2.     ├── src
  3.     |    └── index.js
  4.     ├── package.json
  5.     ├── webpack.config.js

安裝 webpack

 
 
 
 
  1. npm install webpack webpack-cli -D

開始搞事情

在 src/index.js 中隨便寫點東西

 
 
 
 
  1. class Test {
  2.   constructor() {
  3.     document.writeTest('hello world')
  4.   }
  5. }
  6. new Test()

先來打個包看看啥效果, 執(zhí)行命令 npx webpack

等待一段時間后,看到目錄有了變化, 新增了一個 dist 目錄,該目錄下有一個 main.js 文件

 
 
 
 
  1. test-app
  2.   + ├── dist
  3.   + |    └── main.js
  4.     ├── src
  5.     |    └── index.js
  6.     ├── package.json
  7.     ├── webpack.config.js

讓我們來看看 main.js 里有點啥

 
 
 
 
  1. new class{constructor(){document.writeTest("hello world")}};

這玩意都不用試,肯定不得行啊,得將 js 代碼轉(zhuǎn)成 es5 才行。首先安裝下babel-loader及幾個相關(guān)的依賴

配置 babelbabel-loader

  • @babel/core
  • @babel/preset-env
  • @babel/plugin-transform-runtime
  • @babel/plugin-proposal-decorators
  • @babel/plugin-proposal-class-properties
  • @babel/plugin-proposal-private-methods
  • @babel/runtime
  • @babel/runtime-corejs3
 
 
 
 
  1. npm install babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime  @babel/plugin-proposal-decorators  @babel/plugin-proposal-class-properties @babel/plugin-proposal-private-methods -D
  2. npm install @babel/runtime @babel/runtime-corejs3 -s

修改 webpack.config.js 文件, 添加 babel-loader 配置

 
 
 
 
  1. const path = require('path');
  2. module.exports = {
  3.   entry: './src/index.js',
  4.   output: {
  5.     path: path.resolve(__dirname, 'dist'),
  6.     filename: 'bundle.[contenthash:8].js',
  7.   },
  8.   module: {
  9.     rules: [
  10.       {
  11.         test: /\.(jsx|js)$/,
  12.         use: 'babel-loader',
  13.         exclude: /node_modules/,
  14.       },
  15.     ]
  16.   }
  17. }

根目錄下添加相應(yīng)的 .babelrc 配置文件

 
 
 
 
  1. {
  2.     "presets": ["@babel/preset-env"],
  3.     "plugins": [
  4.         ["@babel/plugin-transform-runtime", {"corejs": 3}],
  5.         ["@babel/plugin-proposal-decorators", { "legacy": true }],
  6.         ["@babel/plugin-proposal-class-properties", { "loose": true }],
  7.         ["@babel/plugin-proposal-private-methods", { "loose": true }]
  8.     ]
  9. }

再次執(zhí)行命令 npx webpack 來打個包。完成后查看目錄結(jié)構(gòu)

 
 
 
 
  1. test-app
  2.     ├── dist
  3.   + |    ├── bundle.b8ba1739.js
  4.     |    ├── main.js
  5.     ├── src
  6.     |    └── index.js
  7.   + ├── .babelrc
  8.     ├── package.json
  9.     ├── webpack.config.js

查看構(gòu)建后的 bundle.b8ba1739.js 文件

 
 
 
 
  1. (()=>{"use strict";new function n(){!function(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),document.writeTest("hello world")}})();

構(gòu)建產(chǎn)物看著沒什么問題了,接下來看下在瀏覽器中的實際效果。要看效果,肯定離不開 html 文件。

瀏覽器中觀看效果

作為一個伸手黨直接從社區(qū)嫖來一個插件 html-webpack-plugin,這個插件的作用是將打包產(chǎn)物引入到我們提前準備好的模板 .html 文件中,我們訪問這個文件就能直觀的看到效果了

先來安裝下插件

 
 
 
 
  1. npm install html-webpack-plugin -D

接著創(chuàng)建一個 public 目錄, 用來存放靜態(tài)資源。新增一個 index.html 模板,放在 public 目錄下

 
 
 
 
  1. test-app
  2.     ├── dist
  3.     |    ├── bundle.b8ba1739.js
  4.     |    ├── main.js
  5.     ├── src
  6.     |    └── index.js
  7.   + ├── public
  8.   + |    └── index.html
  9.     ├── .babelrc
  10.     ├── package.json
  11.     ├── webpack.config.js

在 webpack.config.js 中配置 html-webpack-plugin

 
 
 
 
  1. // 省略 ...
  2. const HtmlWebpackPlugin = require('html-webpack-plugin');
  3. module.exports = {
  4.   // 省略 ...
  5.   plugins: [
  6.     new HtmlWebpackPlugin({
  7.       template: path.resolve(__dirname, './public/index.html'),
  8.       inject: 'body',
  9.       scriptLoading: 'blocking',
  10.     }),
  11.   ]
  12. }

再次執(zhí)行命令 npx webpack 來打個包。打完包發(fā)現(xiàn) dist 目錄下多了一個 index.html 文件。瀏覽器中打開 index.html 看看對不對

作為一個 api 工程師,連 api 都能記錯。

修改下 src/index.js 代碼

 
 
 
 
  1. class Test {
  2.   constructor() {
  3.     document.write('hello world')
  4.   }
  5. }
  6. new Test()

再次執(zhí)行命令 npx webpack 來打個包。老步驟,先檢查下打包產(chǎn)物對不對

 
 
 
 
  1. test-app
  2.     ├── dist
  3.     |    ├── bundle.b8ba1739.js
  4.  +  |    ├── bundle.dc044571.js
  5.     |    ├── index.html
  6.     |    ├── main.js
  7.     ├── src
  8.     |    └── index.js
  9.     ├── public
  10.     |    └── index.html
  11.     ├── .babelrc
  12.     ├── package.json
  13.     ├── webpack.config.js

看樣子應(yīng)該沒錯,代碼修改了,打包后多了個 .js 文件。再看看效果對不對

界面上也出現(xiàn)了 hello world。到這里為止,算是利用 webpack 走通了一個最小流程。

為什么說是最小,因為到目前為止這個配置在實際工作中 基本沒卵用 實用性不大。細心一點的人已經(jīng)看出來了,上面存在三個問題

  1. 每修改一次代碼,都要走一遍打包流程,然后自己手動打開 html 文件,預覽效果
  2. 第一次調(diào)用錯誤 api 的時候,報錯信息定位不精確
  3. 打包目錄下面 上次構(gòu)建產(chǎn)物 也仍舊存在,時間長了會存在越來越多的無用代碼

作為一個懶人,第三點可以忍,第一點和第二點忍不了。我們一個個來解決

實時更新并預覽效果針對第一點,查閱 webpack 官網(wǎng),發(fā)現(xiàn)官網(wǎng)就給指了一條明路

按照官網(wǎng)教程,首先安裝下 webpack-dev-server

 
 
 
 
  1. npm install webpack-dev-server -D

再在 webpack.config.js 中添加相應(yīng)的配置

 
 
 
 
  1. // 省略 ...
  2. module.exports = {
  3.   // 省略 ...
  4.   devServer: {
  5.     port: '3001', // 默認是 8080
  6.     hot: true,
  7.     stats: 'errors-only', // 終端僅打印 error
  8.     compress: true, // 是否啟用 gzip 壓縮
  9.     proxy: {
  10.       '/api': {
  11.         target: 'http://0.0.0.0:80',
  12.         pathRewrite: {
  13.           '/api': '',
  14.         },
  15.       },
  16.     },
  17.   },
  18. }

在 package.json > script 中添加一個命令

 
 
 
 
  1. "dev": "webpack serve  --open",

執(zhí)行 npm run dev,這個時候在動在瀏覽器中打開了 http://localhost:3001/ 頁面。光自動打開還不夠啊,我們的目標是每次修改后不用構(gòu)建就能在瀏覽器中實時查看。為了測試這個功能是否生效,我們?nèi)我庑薷?src/index.js 文件并保存。發(fā)現(xiàn)瀏覽器中內(nèi)容自動刷新生效了。

想了解更多關(guān)于 devServer 的可以閱讀以下兩篇文章

  • 【W(wǎng)ebpack】devServer 實驗報告
  • 120 行代碼幫你了解 Webpack 下的 HMR 機制

sourcemap 配置

第一個問題好了,再來看看第二個問題 報錯信息定位不精確。我們?nèi)耘f在官網(wǎng)找找看,有沒有對應(yīng)的解決方案。通過 1 小時的文檔閱讀和 7 小時的摸魚,終于在一天后找到了解決方法。

我們在 webpack.config.js 中添加配置

 
 
 
 
  1. // 省略 ...
  2. module.exports = {
  3.   // 省略 ...
  4.   devtool: 'eval-cheap-module-source-map',
  5. }

這個配置什么意思呢,它會告訴我們錯誤是在原始代碼的哪一行發(fā)生的。廢話不多說,先來看看效果

 點進去看看是什么情況

這么精準的定位,一天可以改100個 bug 了。

但是!!!這玩意好歸好,生產(chǎn)環(huán)境可不能亂用。這里建議

開發(fā)環(huán)境 最佳:eval-cheap-module-source-map生產(chǎn)環(huán)境 最佳:hidden-source-map

什么?你上下嘴皮子吧嗒一合,說最佳就最佳?沒有拿得出手的理由我們是不會信的

造謠是不可能造謠的,這輩子都不會。我也是吸收了這篇文章 萬字長文:關(guān)于 sourcemap,這篇文章就夠了 的精華才總結(jié)出來的。

一萬字的文章總結(jié)成兩句話,10 秒鐘吸收

世事總是這么奇妙,按照上面的思路,在解決第二個問題的時候又帶出了一個新的問題,某些配置可能需要區(qū)分環(huán)境來設(shè)置,不同的環(huán)境設(shè)置合適的配置。就像在解決一個bug A的過程中,發(fā)現(xiàn)了一個新的 bug B??磥碓诮鉀Q上面第三個問題之前,得先解決這個 區(qū)分環(huán)境配置 的問題了。

拆分環(huán)境

按照一般慣例,我們會有 開發(fā)、測試、預發(fā)、生產(chǎn)幾個環(huán)境。但是我個人很多情況下 開發(fā) 和 測試 環(huán)境是同一套配置,所以我這里直接省略 測試 這個環(huán)境。

修改下目錄結(jié)構(gòu)

 
 
 
 
  1. test-app
  2.   + ├── build
  3.   + |    ├── webpack.base.js
  4.   + |    ├── webpack.dev.js
  5.   + |    ├── webpack.pre.js
  6.   + |    ├── webpack.pro.js
  7.     ├── dist
  8.     ├──  ├── bundle.b8ba1739.js
  9.     ├──  ├── bundle.dc044571.js
  10.     |    ├── index.html
  11.     |    ├── main.js
  12.     ├── src
  13.     |    └── index.js
  14.     ├── public
  15.     |    └── index.html
  16.     ├── .babelrc
  17.     ├── package.json

從目錄中就可以看出一點東西,我們刪除了原先根目錄下的 webpack.config.js 文件。新增了一個 build 目錄。在 build 目錄下我們需要建一個 webpack.base.js 文件。用來存放各個環(huán)境公共的配置,畢竟不可能所有配置在各個環(huán)境中都不一樣。然后按照我們各自項目實際的需求來建立不同環(huán)境的配置文件。

先修改公共配置文件 webpack.base.js。原先的 devServe 配置由于只有開發(fā)環(huán)境有;devtool 各個環(huán)境不一樣,所以這兩個配置從公共配置里移除了

 
 
 
 
  1. const path = require('path');
  2. const HtmlWebpackPlugin = require('html-webpack-plugin');
  3. const rootDir = process.cwd();
  4. module.exports = {
  5.   entry: path.resolve(rootDir, 'src/index.js'),
  6.   output: {
  7.     path: path.resolve(rootDir, 'dist'),
  8.     filename: 'bundle.[contenthash:8].js',
  9.   },
  10.   module: {
  11.     rules: [
  12.       {
  13.         test: /\.(jsx|js)$/,
  14.         use: 'babel-loader',
  15.         include: path.resolve(rootDir, 'src'),
  16.         exclude: /node_modules/,
  17.       },
  18.     ]
  19.   },
  20.   plugins: [
  21.     new HtmlWebpackPlugin({
  22.       template: path.resolve(rootDir, 'public/index.html'),
  23.       inject: 'body',
  24.       scriptLoading: 'blocking',
  25.     }),
  26.   ],
  27. }

接下來配置各個環(huán)境的配置,這里主要用到一個 webpack-merge 插件,用來合并公共配置,執(zhí)行 npm install webpack-merge -D

修改 webpack.dev.js

 
 
 
 
  1. const { merge } = require('webpack-merge');
  2. const baseConfig = require('./webpack.base');
  3. module.exports = merge(baseConfig, {
  4.   mode: 'development',
  5.   devtool: 'eval-cheap-module-source-map',
  6.   devServer: {
  7.     port: '3001', // 默認是 8080
  8.     hot: true,
  9.     stats: 'errors-only', // 終端僅打印 error
  10.     compress: true, // 是否啟用 gzip 壓縮
  11.     proxy: {
  12.       '/api': {
  13.         target: 'http://0.0.0.0:80',
  14.         pathRewrite: {
  15.           '/api': '',
  16.         },
  17.       },
  18.     },
  19.   },
  20. });

因為這里不涉及到實際的項目開發(fā),所以這里預發(fā)和生產(chǎn)兩個環(huán)境的文件先配置成一樣的,大家可以根據(jù)自己的實際需要來進行不同的配置。

  • webpack.pre.js
  • webpack.pro.js
 
 
 
 
  1. const { merge } = require('webpack-merge');
  2. const baseConfig = require('./webpack.base');
  3. module.exports = merge(baseConfig, {
  4.   mode: 'production',
  5.   devtool: 'hidden-source-map',
  6. });

看到仔細的人已經(jīng)發(fā)現(xiàn),配置中多了一個 mode 屬性,這個會在后面解釋一波,這里先不講

修改 package.json 中的命令

 
 
 
 
  1. "scripts": {
  2.   "dev": "webpack serve --config build/webpack.dev.js --open",
  3.   "build:pro": "npx webpack --config build/webpack.pro.js",
  4. },

再次執(zhí)行 npm run dev 看看效果

看來是沒問題了,現(xiàn)在已經(jīng)成功把 webpack.config.js 文件根據(jù)環(huán)境進行拆分成了多個文件。

現(xiàn)在來回顧下之前提出的第三個問題

這個項目小的時候其實問題不大,但是當項目大了之后,每次打包都增加幾百上千的文件,還是有點恐怖的。所以還是把這個問題也順帶解決下好了。

打包時清除上次構(gòu)建產(chǎn)物

我們的目標是每次打包時刪除上次打包的產(chǎn)物,保證打包目錄下所有文件都是新的,社區(qū)查找一番后,找到一個插件clean-webpack-plugin ,來看下這個插件的介紹

比較懶,所以直接上截圖了。老步驟,先安裝 npm install clean-webpack-plugin -D 然后直接將文檔中的示例代碼借鑒到我們的項目中。修改 webpack.base.js

 
 
 
 
  1. // 省略...
  2. const { CleanWebpackPlugin } = require('clean-webpack-plugin');
  3. module.exports = {
  4.   // 省略...
  5.   plugins: [
  6.     new HtmlWebpackPlugin({
  7.       template: path.resolve(rootDir, 'public/index.html'),
  8.       inject: 'body',
  9.       scriptLoading: 'blocking',
  10.     }),
  11.     new CleanWebpackPlugin(),
  12.   ],
  13. }

試下效果,執(zhí)行 npm run build:pro 打個包。查看目錄

 
 
 
 
  1. test-app
  2.     ├── build
  3.     |    ├── webpack.base.js
  4.     |    ├── webpack.dev.js
  5.     |    ├── webpack.pre.js
  6.     |    ├── webpack.pro.js
  7.     ├── dist
  8.     |    ├── bundle.fd44c2eb.js
  9.     |    ├── bundle.fd44c2eb.js.map
  10.     |    ├── index.html
  11.     ├── src
  12.     |    └── index.js
  13.     ├── public
  14.     |    └── index.html
  15.     ├── .babelrc
  16.     ├── package.json

dist 目錄下原先存在的 main.js、bundle.b8ba1739.js 等前幾次打包產(chǎn)物已經(jīng)自動清除了。到這里第三個問題也解決了

功能完善

添加 css 和 less 支持

為什么不添加 sass 支持?因為我不用 sass

首先,在 src 目錄下添加一個 index.less 文件

 
 
 
 
  1. .test {
  2.   color: red;
  3. }

修改 src/index.js 文件,在文件中引用剛才添加的 less 文件

 
 
 
 
  1. import './index.less'
  2. class Test {
  3.   constructor() {
  4.     this.renderDiv()
  5.   }
  6.   renderDiv() {
  7.     const div = document.createElement('div')
  8.     div.className = 'test'
  9.     div.innerHTML = 'hello world'
  10.     document.body.appendChild(div)
  11.   }
  12. }
  13. new Test()

執(zhí)行 npm run dev

等待 10 分鐘后,頁面遲遲沒有加載任何東西,打開控制臺一看

英語 8 級的我立馬讀懂了報錯:"你 可能 需要 一個 什么什么 loader 來 處理 這個 文件 類型, 目前 沒有 loaders 被配置 來 process 這個 文件"

再結(jié)合官網(wǎng)的說明

到了這里,我好像隱約明白了 webpack 的真諦:雖然很多時候我不行,但是很多大佬會讓我行。呸,什么叫不行?這叫 靈活可插拔,正是這種特性,讓 webpack 可靈活支持各種復雜場景的自定義配置。

忘了正事兒,既然問題找到了,就好解決了,找到幾個處理 css 和 less 的 loader 就行

首先安裝 loader

 
 
 
 
  1. npm install less style-loader css-loader less-loader -D

再修改 webpack.base.js 文件

 
 
 
 
  1. // 省略...
  2. module.exports = {
  3.   // 省略...
  4.   module: {
  5.     rules: [
  6.       // 省略...
  7.       {
  8.         test: /\.(le|c)ss$/,
  9.         exclude: /node_modules/,
  10.         use: ['style-loader', 'css-loader', 'less-loader']
  11.       },
  12.     ]
  13.   },
  14.   // 省略...
  15. }

再次執(zhí)行 npm run dev,查看效果

css module

這一塊是基于上面的模塊修改的,解決 css 命名混亂和沖突的。不需要的話可以直接跳過這一塊。

修改 webpack.base.js

 
 
 
 
  1. // 省略...
  2. module.exports = {
  3.   // 省略...
  4.   module: {
  5.     rules: [
  6.       //  省略...
  7.       {
  8.         test: /\.(le|c)ss$/,
  9.         exclude: /node_modules/,
  10.         use: [
  11.           'style-loader',
  12.           {
  13.             loader: 'css-loader',
  14.             options: {
  15.               modules: {
  16.                 compileType: 'module',
  17.                 localIdentName: "[local]__[hash:base64:5]",
  18.               },
  19.             },
  20.           },
  21.           'less-loader'
  22.         ]
  23.       },
  24.     ]
  25.   },
  26.   // 省略...
  27. }

執(zhí)行 npm run dev 來看看效果

給 class 樣式名稱后加上一個哈希串,具體的配置可以看 css-loader 官網(wǎng)

css 自動添加前綴

首先安裝插件

 
 
 
 
  1. npm install autoprefixer postcss postcss-loader -D

修改 webpack.base.js 配置文件

 
 
 
 
  1. // 省略...
  2. const autoprefixer = require('autoprefixer');
  3. module.exports = {
  4.   // 省略...
  5.   module: {
  6.     rules: [
  7.       // 省略...
  8.       {
  9.         test: /\.(le|c)ss$/,
  10.         exclude: /node_modules/,
  11.         use: [
  12.           // 省略...
  13.           'less-loader',
  14.           {
  15.             loader: 'postcss-loader',
  16.             options: {
  17.               postcssOptions: {
  18.                 plugins: [
  19.                   ["autoprefixer"],
  20.                 ],
  21.               },
  22.             },
  23.           }
  24.         ]
  25.       },
  26.     ]
  27.   },
  28.   // 省略...
  29. }

打包后抽離 css 文件

首先安裝 mini-css-extract-plugin 插件

 
 
 
 
  1. npm install mini-css-extract-plugin -D

修改 webpack.base.js 配置文件

 
 
 
 
  1. // 省略...
  2. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  3. module.exports = {
  4.   // 省略...
  5.   module: {
  6.     rules: [
  7.       // 省略...
  8.       {
  9.         test: /\.(le|c)ss$/,
  10.         exclude: /node_modules/,
  11.         use: [
  12.           MiniCssExtractPlugin.loader,
  13.           // 省略...
  14.         ]
  15.       },
  16.     ]
  17.   },
  18.   plugins: [
  19.     // 省略...
  20.     new MiniCssExtractPlugin({
  21.       filename: 'css/[name].css',
  22.     }),
  23.   ],
  24. }

執(zhí)行 npm run build:pro 打個包看看效果。

可以看到 css 已經(jīng)被抽離出來了

壓縮打包后的 css 文件

首先安裝 optimize-css-assets-webpack-plugin 插件

 
 
 
 
  1. npm install optimize-css-assets-webpack-plugin -D

修改 webpack.base.js 配置文件

 
 
 
 
  1. // 省略...
  2. const OptimizeCssPlugin = require('optimize-css-assets-webpack-plugin');
  3. module.exports = {
  4.   // 省略...
  5.   plugins: [
  6.     // 省略...
  7.     new MiniCssExtractPlugin({
  8.       filename: 'css/[name].css',
  9.     }),
  10.     new OptimizeCssPlugin(),
  11.   ],
  12. }

執(zhí)行 npm run build:pro 打個包看看效果。

 
 
 
 
  1. .test__1PSRs{color:red;transition-duration:.4s}

可以看出 css 已經(jīng)被壓縮了

復制靜態(tài)資源到打包目錄

有些時候有些第三方的 js 插件沒有提供 npm 包,只提供了一個 cdn 地址或者一份文件需要自己下載下來。通常我們下載下來之后放在我們的 public/js 目錄下面,然后 public/index.html 文件里直接用 script 標簽引入。這個時候不管是 npm run dev 開發(fā)時,還是 npm run build:pro 構(gòu)建后,這個 js 文件都是找不到的。我們可以嘗試下

在 public/js 新加一個 test.js 的空文件,啥內(nèi)容都不用。然后在 public/index.html 中引入這個文件

 
 
 
 
  1.   
  2.     // 省略
  3.   
  4.   
  5.     
  •     
  •   
  • 執(zhí)行 npm run dev 查看效果

    這里我們可以用 copy-webpack-plugin 這個插件,在構(gòu)建的時候,將 public/js 的靜態(tài)資源復制到 dist 目錄下,這樣文件就能找到了

    安裝插件 npm install copy-webpack-plugin -D

    修改 webpack.base.js 配置文件

     
     
     
     
    1. // 省略...
    2. const CopyWebpackPlugin = require('copy-webpack-plugin');
    3. const rootDir = process.cwd();
    4. module.exports = {
    5.   // 省略...
    6.   plugins: [
    7.     new HtmlWebpackPlugin({
    8.       template: path.resolve(rootDir, 'public/index.html'),
    9.       inject: 'body',
    10.       scriptLoading: 'blocking',
    11.     }),
    12.     new CleanWebpackPlugin(),
    13.     new CopyWebpackPlugin({
    14.       patterns: [
    15.         {
    16.           from: '*.js',
    17.           context: path.resolve(rootDir, "public/js"),
    18.           to: path.resolve(rootDir, 'dist/js'),
    19.         },
    20.       ],
    21.     })
    22.     new MiniCssExtractPlugin({
    23.       filename: 'css/[name].css',
    24.     }),
    25.     new OptimizeCssPlugin(),
    26.   ],
    27. }

    執(zhí)行 npm run dev 查看效果

    靜態(tài)文件已經(jīng)可以正常加載了。

    資源加載器

    項目中難免要引入一些圖標、圖片等資源,在不做任何處理的情況下,我們嘗試下在代碼中引用圖片,修改 src/index.js 文件如下

     
     
     
     
    1. import wuhanjiayou from '../public/asset/a.jpeg'
    2. class Test {
    3.   constructor() {
    4.     this.renderImg()
    5.   }
    6.   renderImg() {
    7.     const img = document.createElement('img')
    8.     img.src = wuhanjiayou
    9.     document.body.appendChild(img)
    10.   }
    11. }
    12. new Test()

    執(zhí)行 npm run dev 看下效果,報了個熟悉的錯

    按照以往的套路,直接引用社區(qū)的三件套 raw-loader、url-loader、file-loader,安裝依賴,配置依賴,一通操作下來就解決了問題?,F(xiàn)在我們使用 webpack5就方便多了,不用安裝任何依賴,直接修改 webpack.base.js 配置文件

     
     
     
     
    1. // 省略...
    2. rules: [
    3.     {
    4.         test: /\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,
    5.         type: 'asset',
    6.     },
    7. ]

    沒錯,就是這么簡單。type 屬性還有其他幾個值,具體可以看 官方文檔

    配置已經(jīng)修改好了,執(zhí)行 npm run dev 再來看下效果

    搞定!

    上面講到的東西基本夠小項目的日常開發(fā)需求了,常用的 loader 和 plugin 都已經(jīng)有所涉及。但是,如果你的項目特別復雜,需求又比較小眾,社區(qū)沒有現(xiàn)成的 loader 和 plugin 可以借鑒,那么只能自己動手實現(xiàn)一個了。

    可能在一部分人眼中,loader 和 plugin 是比較神秘的,也不可能想著自己去造一個輪子。但是當碰到問題又沒有現(xiàn)成的解決方案的時候,那就不得不自己造了。

    看了這篇文章 Webpack - 手把手教你寫一個 loader / plugin 應(yīng)該能很快上手

    項目優(yōu)化

    剛才也講到了,上面的一通操作基本夠小項目開發(fā)使用了。為什么是小項目?大項目不行嗎?當一個項目大到路由都有幾百個的時候,一次熱更新就需要十幾二十多秒,一次打包要半個小時。開發(fā)時,一次代碼改動保存就要等 20 秒,這擱誰誰都忍不了啊。這個時候就需要想點辦法來優(yōu)化。

    loader 配置優(yōu)化

    這個其實上面已經(jīng)做了。明確告訴 loader,哪些文件不用做處理(exclude),或者只處理哪些文件(include)。

     
     
     
     
    1. {
    2.     test: /\.(jsx|js)$/,
    3.     use: 'babel-loader',
    4.     // include: [path.resolve(rootDir, 'src')]
    5.     // exclude: /node_modules/,
    6.   },

    一般傾向于使用 include,但是如果怕漏處理一些文件的話,粗暴點,使用 exclude: /node_modules/ 也可以。

    這部分測試了下,提升速度不是很明顯,應(yīng)該算錦上添花吧

    緩存

    先說下 webpack5 之前是怎么做的。

    利用 cache-loader 將結(jié)果緩存中磁盤中;利用 hard-source-webpack-plugin 將結(jié)果緩存在 node_modules/.cache 下提升二次打包速度;利用 DllReferencePlugin 將變化不頻繁的第三方庫提前單獨打包成動態(tài)鏈接庫,提升真正業(yè)務(wù)代碼的打包速度

    webpack5 自帶了持久化緩存,配置如下

    開發(fā)環(huán)境 webpack.dev.js

     
     
     
     
    1. cache: {
    2.     type: 'memory'
    3. },

    生產(chǎn)環(huán)境 webpack.pro.js

     
     
     
     
    1. cache: {
    2.     type: 'filesystem',
    3.     buildDependencies: {
    4.       config: [__filename]
    5.     }
    6. },

    這個測試了下前后的打包時間

    數(shù)據(jù)是這個數(shù)據(jù):

    • 第一次: 12592 ms
    • 第二次: 920 ms但是我心里默數(shù)了下,二次打包大概在 3 秒左右,咱也不知道控制臺的計時邏輯是什么

    如果在構(gòu)建時,你主動確定要放棄舊的緩存的話,可以傳一個新的 version 參數(shù)來放棄使用緩存

     
     
     
     
    1. cache: {
    2.     type: 'filesystem',
    3.     buildDependencies: {
    4.       config: [__filename]
    5.     },
    6.     version: 'new_version'
    7. },

    代碼拆分

     
     
     
     
    1. optimization: {
    2.     splitChunks: {
    3.       chunks: 'all',
    4.     }
    5. }

    這個在 mode: production 時是默認開啟的,但是默認情況下只會對按需加載的代碼進行分割。如果我們要對一開始就加載的代碼也做分割處理,就要進行如上配置。

    從官網(wǎng)截了一張圖:

    大家的項目可能都有所不同,相對應(yīng)的最佳的配置可能也有所不同,所以這里就補貼具體的配置了,大家有需要的可以看官網(wǎng)的文檔對自己的項目進行配置 官網(wǎng) optimization.splitChunks 更多配置、「Webpack」從 0 到 1 學會 code splitting

    mode

    mode: production 在上面出現(xiàn)了這么多次,也沒有具體說有哪些功能。其實當設(shè)置 mode: production 時,webpack 已經(jīng)默認開啟了一些優(yōu)化措施。

    這里面的一些東西由于篇幅較大也不做一一說明了,反正只要記得 mode: production 已經(jīng)給我們做了一系列優(yōu)化,真的想知道有哪些優(yōu)化的,我找了篇文章,有興趣的可以看看 mode 詳解

    happypack

    利用 happypack 插件進行多線程打包,按照官網(wǎng)文檔進行配置

     
     
     
     
    1. // 省略...
    2. const Happypack = require('happypack');
    3. const os = require('os')
    4. const happyThreadPool = Happypack.ThreadPool({ size: os.cpus().length })
    5. // 省略...
    6. rules: [
    7.   {
    8.     test: /\.(jsx|js)$/,
    9.     // use: 'babel-loader',
    10.     use: 'Happypack/loader?id=js',
    11.     exclude: /node_modules/,
    12.   },
    13. ]
    14. plugins: [
    15.     new Happypack({
    16.       id: 'js', // 這個 id 值為上面 Happypack/loader?id=js 問號后跟的參數(shù)
    17.       use: ['babel-loader'],
    18.       threadPool: happyThreadPool
    19.     }),
    20. ]

    由于本篇文章寫的是個 demo,沒有業(yè)務(wù)代碼,所以這個打包出來的時間基本沒變化甚至還多了 1 秒,這里就不貼效果圖了。這是因為happypack執(zhí)行也需要時間,如果項目比較小的話,就不需要配置了。js 處理完之后那就是要處理css了, 按照處理js的方式,ctrl+c/ctrl+v 處理css。

    執(zhí)行 npm run build:pro

     
     
     
     
    1. ERROR in ./src/index.less
    2. Module build failed (from ./node_modules/Happypack/loader.js):
    3. Error: You forgot to add 'mini-css-extract-plugin' plugin (i.e. `{ plug
      文章題目:一篇帶給你webpack優(yōu)秀實踐
      鏈接分享:http://m.5511xx.com/article/dphcipo.html