主頁 >  其他 > 一篇弄懂webpack靜態資源打包器

一篇弄懂webpack靜態資源打包器

2020-10-02 11:58:19 其他

認識

webpack是優秀的前端構建工具,靜態資源打包器,可以根據模塊依賴關系進行靜態資源分析,快速打包生成相對應瀏覽器可以直接識別的靜態資源!

環境

1)node環境

2)vs code編輯器

規約

1)入口檔案:

開始打包第一個檔案稱為入口檔案,通常經過在入口檔案中引入其他資源,形成資源關系樹狀圖,webpack根據依賴關系進行一次處理,

2)chunk代碼塊:

管理webpack內部的打包行程,chunk可以分為“入口”和“子代碼塊”,入口檔案就是一個chunk,默認的webpack打包配置是一個入口檔案是一個chunk,打包生成一個bundle,但是如果出現代碼分割的情況下,有多個chunk打包生成一個bundle,

3)bundle:

通過處理入口檔案中的關系依賴,最后打包輸出成為瀏覽器可以直接識別的靜態資源檔案就是bundle,

安裝webpack環境

1)專案根目錄控制臺執行指令:npm init,生成package.json檔案,npm是新版本node自帶的包管理工具,而package.json相當于清單,記錄依賴庫和專案資訊的檔案,

2)全域安裝webpack指令: npm i webpack webpack-cli -g ,全域安裝是指系統環境中,任何專案檔案夾下都可以使用指令,其中mac電腦首次執行應該是需要管理員權限,sudo npm i webpack webpack-cli -g 如果網速太慢則建議切換為淘寶鏡像源,

3)本地安裝webpcak指令: sudo npm i webpack webpack-cli -D,下載的模塊是注入于本專案下的./node_nodules檔案夾中,不會影響其他專案,起到獨立的作用!

概念核心:

Entry

入口檔案指示,配置wepack以哪個入口檔案進行打包分析等引數,

entry: "./src/main.js",

Output

出口檔案指示,配置webpack打包后的資源bundle輸出資源的路徑及引數,

output: {
  filename: "static/js/[name].js",
  path: resolve(__dirname, "build"),
},

Loader

webpack本身僅能識別js、json代碼,而Loader的作用就是將CSS、img、字體資源翻譯成為webpack可以識別的資源,可以識別后才可以進行打包處理!loader通過npm安裝依賴之后就可以配置,不用需要引入,

1)Es語法檢查配置:
// eslint語法檢查
{
  /**
   * js語法所需loader安裝指令:npm i eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import -D
   * eslint的js語法檢查是依托于airbnb規則進行檢查,根據package.json下的eslintConfig的配置進行檢測語法,
   * airbnb默認是不能認識window等物件,可通過eslintConfig下的env屬性進行屏蔽檢查,可通過eslint-disable-next-line注釋取消下一行的語法檢查,
   */
  test: /\.js$/, // 通過正則匹配后綴名為.js的檔案
  enforce: "pre", // 設定loader的執行順序,pre(優先)| post(延后),
  exclude: /node_modules/, // 排除node_modules目錄下js檔案的語法檢查
  loader: "eslint-loader", // 指定eslint-loader執行處理js檔案進行語法檢查
  options: {
    fix: true, // 配置參、空格、縮進不規范的語法自動進行修復,
  },
},
2)處理CSS檔案并兼容:
{
	// 處理css檔案的規則所需loader安裝指令:npm i style-loader -D 和 npm i css-loader -D
	test: /\.css$/,
	// 處理檔案時使用到多個lorder時,執行順序為從下到上,
	use: [
	  // "style-loader", // 處理創建style標簽,將js中處理的資源添加到style標簽中,再添加到頁面head中生效,
	  {
	    loader: MiniCssExtractPlugin.loader, // 因為css引入js檔案中,會造成js代碼檔案過大,所以通過MiniCssExtractPlugin建構式自帶loader取代style-loader,作用為將css抽離成為單個檔案通過link標簽引入,
	    options: {
	      publicPath: "../../", // 資源引入html檔案時的路徑前綴,因為css檔案以及被單獨抽離至特定目錄下,正確修改才能匹配到css中參考的靜態資源,
	    },
	  },
	  // 翻譯css使webpack能夠識別css樣式語法
	  "css-loader",
	  {
	    loader: "postcss-loader", // 使用postcss進行瀏覽器兼容,使用的方法是在package.json中定義browserslist屬性規則進行瀏覽器兼容性語法補全,
	    options: {
	      ident: "postcss",
	      plugins: () => [require("postcss-preset-env")],
	    },
	  },
	],
},
3)處理Less檔案:
{
  // 處理less檔案的規則所需loader安裝指令:npm i less-loader -D 和 npm i less -D
  test: /\.less$/,
  use: [
    // "style-loader",
    {
      loader: MiniCssExtractPlugin.loader,
      options: {
        publicPath: "../../",
      },
    },
    "css-loader",
    "less-loader",
  ],
},
4)處理圖片檔案:
{
   // 處理圖片檔案的規則安裝指令:cnpm i url-loader file-loader  -D
   test: /\.(png|jpe?g|gif|gif|svg)(\?.*)?$/,
   loader: "url-loader",
   options: {
     limit: 80 * 1024, // 當圖片小于80kb時采用base64的方式打包,大于則以圖片形式打包,
     name: "[hash:10].[ext]", // 每次webpack構建打包會生成一串不重復的hash碼,[hash:10]則是去hash的前十位,[ext]取源檔案的后綴名,
     outputPath: "static/img", // 輸出目錄,output定義了輸出目錄為build,此處圖片輸出目錄為build/static/img/XXX檔案,
     esModule: false, // 默認使用es6語法決議,html-loader使用的是commonjs語法引入,但2020年09月24日不用關閉url-loader的es6決議方法,
   },
},
5)處理html檔案引入的圖片:
{
  // 處理html中img等標簽引入的圖片資源所需loader安裝指令:npm i html-loader  -D
  test: /\.html$/,
  loader: "html-loader", // 處理url-loader僅能處理打包圖片而不能處理html中資源的遺留問題,
},
6)處理字體圖示:
{
  // 處理引入字體圖示資源所需loader安裝指令:npm install file-loader -D
  test: /(\.(ttf|woff|eot)$|iconfont\.svg)/,
  loader: "file-loader",
  options: {
    name: "[hash:10].[ext]",
    outputPath: "static/font",
  },
},
7)處理JS檔案并兼容:
{
  /**
   * 處理es6語法轉es5語法和Promise等新增屬性所需的loader安裝指令:npm i babel-loader @babel/preset-env @babel/core @babel/polyfill core-js -D
   * 關于解決Promise等新增技術IE舊(垃)版(圾)瀏覽器不能識別的問題:
   * 1)入口檔案中首行添加import '@babel/polyfill' 引入模塊,簡單方便,但會引入不必要的兼容配置,造成代碼體積偏大,
   * 2)按需加載比較推薦
   */
  test: /\.js$/,
  exclude: /node_modules/,
  use: [
    {
      /**
       * 開啟多行程打包所需loader安裝指令:npm install thread-loader -D
       * 可以給每一個規則使用這個loader,但是建議只給js進行,因為js打包花費的時間很多,建議專案足夠大時打開多行程打包,開啟經常需要600ms,行程通信也有開銷,
       */
      // ,
      loader: "thread-loader", // 建議專案足夠大時打開多行程打包,開啟經常需要600ms,行程通信也有開銷,
      options: {
        works: 4, // 核數
      },
    },
    {
      loader: "babel-loader",
      options: {
        presets: [
          // "@babel/preset-env" // 把下面陣列的注釋掉不會適配Promise等高級技術了,僅僅會轉換let、const、箭頭函式,
          [
            "@babel/preset-env",
            {
              useBuiltIns: "usage",
              corejs: {
                version: 3,
              },
              // 兼容范圍
              targets: {
                chrome: "50",
                firefox: "50",
                ie: "10",
                safari: "10",
                edge: "18",
              },
            },
          ],
        ],
        // 開啟JS代碼快取,當檔案名不變時,瀏覽器強制快取js檔案,導致修改的專案不能實時更新,所以應該在output中輸出檔案名中包含hash值,采用的是[content:10]的根據內容生成hash值的形式,沒有采用hash是因為css在js中引入屬于同一個chunk,輸出時帶有同一個hash值,
        cacheDirectory: true,
      },
    },
  ],
},

Plugins

插件(plugins)可以讓webpack執行范圍更廣更為復雜的任務,配置打包優化等一下相關的作用功能,使用前需要單獨引入對應的插件,

1)處理html檔案插件:
// 無template屬性時,默認在輸出目錄創建一個空的html檔案,并將打包后的資源引入其中,template指明檔案時,則復制檔案,并引入打包后的資源,
new HtmlWebpackPlugin({
  template: "./src/index.html",
  minify: {
    collapseWhitespace: true, // 清除空行縮進
    removeAttributeQuotes: true, // 清除注釋
  },
}),
2)抽離CSS成單獨檔案插件:
// 處理CSS從js檔案中抽離生成獨立檔案
new MiniCssExtractPlugin({
   filename: "static/css/app.css", // 檔案輸出目錄
 }),
3)壓縮CSS插件:
// Css壓縮插件,需要在package.json中定義sideEffects屬性防止它壓縮去除掉一些css,less等檔案,
new OptimizeCssAssetsWebpackPlugin(),
4)PWA離線訪問技術插件:
// PWA離線快取技術,優化使用體驗,網路斷開后重繪網頁仍能夠加載得到已經快取的資源檔案,依靠service Workers技術,插件執行后生成一個servicework組態檔,需要在入口檔案中注冊,兼容性判斷,
new WorkboxWebpackPlugin.GenerateSW({
  clientsClaim: true, // 幫助servicework快速啟動
  skipWaiting: true, // 洗掉舊版本使用最新的serviceworker技術
}),
5)忽略庫并動態引入第三方庫插件:
/**
 * dll動態引入單獨庫
 * 通過manifest.json檔案中的映射關系,構建打包時進行忽略打包哪些庫,再通過addAssetHtmlWebpackPlugin引入獨立打包的庫,
 */
new webpack.DllReferencePlugin({
  manifest: resolve(__dirname, "dll/manifest.json"),
}),
new addAssetHtmlWebpackPlugin({
  filepath: resolve(__dirname, "dll/jquery.js"),
}),

Mode

配置webpack的作業方式,其中有開發(development)和生產(production)模式,開發環境配置簡單,能夠使代碼能夠跑在本地即可,生產模式相關復雜,需要處理網站運行上線時的優化等操作,

// mode: "development",
mode: "production", // 設定webpack的作業環境

開發環境優化

HMR熱模塊替換

webpack處于開發環境中時,默認是一個模塊發生改變,全部模塊均會重新加載,為了解決此問題,引入HMR熱模塊替換,資源發生改變時,僅會重新構建打包發生改變的模塊,

1)樣式檔案會自動熱模塊替換,因為style-loader內部實作了這個功能,

2)開啟HMR后html默認是不會自動更新,入口檔案中引入html檔案,但默認是不會對html做HMR,

entry: ["./src/main.js", "./index.html"],

3)js代碼發生改變默認也不可以發生更新,入口檔案中對此進行監聽!

// 判斷是否開啟HRM熱模塊更新,如果開啟則監聽所需的js檔案,則熱模塊替換發生作用,
if (module.hot) {
  // 對入口檔案中引入的依賴進行熱部署替換監聽
  module.hot.accept("./utils/url.js", () => {
    // 一旦監聽到發生改變,立即執行該回呼函式,
    getUrl();
  });
}

快取方式提高構建速度

1)babel快取:

配置處理js的loader設定cacheDirectory:
true,會強制js快取一定時間,但是會造成開發環境代碼改變后,生產環境下代碼讀取的是快取中的代碼,造成不能實時更新代碼的問題,

2)檔案資源快取:

  • hash:webpack每次打包構建時會生成一個唯一的hash值,將打包輸出的檔案名字中帶有hash值,則每次改動,重繪均要請求所有資料,不會讀取快取里的資源,造成了js,css快取失效,

  • chunkhash:根據打包時引入的chunk生成hash值,如果打包資源來自同一個資源檔案件中,hash值就一致,因為css是在js中引入,chunk一致,導致js,變化css也會跟著不會讀取快取,

  • contenthash: 根據檔案內容生成hash值,不同引入檔案的hash值就不一樣,

output: {
    filename: "static/js/[name][contenthash:5].js",
    path: resolve(__dirname, "build"),
  },

生產環境優化

Tree Shaking樹搖

打包構架去除無用代碼,必須是使用ES6模塊化引入以及必須指定production環境,自動開啟treeshaking模式,減少代碼體積,package.json中配置sideEffects: false所有代碼均開啟樹搖模式,但可能會干掉無辜的css等檔案, 若標記為sideEffects: ["*.css"]時則不會干掉所匹配的檔案,

JS代碼懶加載

通過es6語法引入,延時加載,觸發一定行為才進行請求加載,不是開局就全部加載進來,那樣會增加首次加載的時間,也有著代碼分隔的特性,會被單獨分割成一個單獨檔案,

// 動態js引入,單獨打包生成一個檔案,并給定檔案名,也會有懶加載的現象,添加預加載webpackPrefetch關鍵字,
import(/*webpackChunkName: 'test',webpackPrefetch: true*/ "./test.js")
  .then((res) => {
    console.log("檔案加載成功", res);
  })

  .catch((err) => {
    console.log("檔案加載失敗", err);
  });

預加載

等其他瀏覽器空閑了再偷偷加載,請求到檔案資料了,觸發行為的時候再去讀取快取中的資料,懶加載的方式上添加添加預加載webpackPrefetch關鍵字,

代碼分割code split

1)多入口檔案方式分隔,物件多入口形式,生成多個chunk,構建后形成多個js檔案,用于代碼分隔,

// entry: {
//   index: "./src/index.js",
//   test: ["./src/test.js"], // 特殊陣列寫法
// },

2)optimization配置分隔,將node_modules的庫單獨分割打包成vendors.js檔案,

optimization: {
    splitChunks: {
      chunks: "all", // 所有配置均為默認
    },
}

3)入口檔案中動態js引入的方式,具有懶加載以及會鏡像代碼分割,

import(/*webpackChunkName: 'add',webpackPrefetch: true*/ "assets/js/add.js")
  .then((res) => {
    console.log("檔案加載成功", res);
  })

  .catch((err) => {
    console.log("檔案加載失敗", err);
  });

PWA漸進式網路開發應用技術(離線訪問)

無網路時,重繪仍然可以訪問到已經加載的網頁,借助了workbox-webpack-plugin插件進行實作,安裝指令:cnpm iworkbox-webpack-plugin -D,且必須運行在服務器中才可以看到結果,

安裝靜態資源服務器

1)npm install serve -g

2)專案根目錄執行指令: serve -s,默認發布打包目錄build下的index.html到靜態資源服務器,

配置插件

new WorkboxWebpackPlugin.GenerateSW({
  clientsClaim: true, // 幫助servicework快速啟動
  skipWaiting: true, // 洗掉舊版本使用最新的serviceworker技術
}),

入口檔案作兼容性判斷

// 注冊serviceWork并處理兼容性問題
if ("serviceWorker" in navigator) {
  window.addEventListener("load", () => {
    navigator.serviceWorker
      .register("/service-worker.js")
      .then((res) => {
        // eslint-disable-next-line
        console.log("注冊成功", res);
      })
      .catch((err) => {
        // eslint-disable-next-line
        console.log("注冊失敗", err);
      });
  });
}

Source-Map映射技術

構建后代碼到源代碼的有一種映射技術,如果構建代碼出錯了,通過映射關系能找到源代碼的位置,非常利于除錯代碼,但是也會造成代碼被盜用的安全性問題,詳細引數移步webpack.config.js中查看,

/**
 * Inline-source-map:行內map檔案不會單獨生成xxx.js.map檔案 直接生成一個map資訊放在打包后的js檔案的最后 構建速度會更快
 * Hidden-source-map:默認設定 生成外部的map資訊檔案
 * Eval-source-map:同樣也是行內map資訊 在每一個引入的資源后面均生成一個map資訊
 * 引數
 * source-map:錯誤代碼的準確資訊和源代碼的錯誤位置 并且能夠匯出對應的源代碼
 * inline-source-map:列印輸出的檔案位置 可定位到源代碼的位置
 * hidden-source-map:列印輸出的是打包后的代碼 可定位到定位打包后的位置 不可以追溯到源代碼的位置
 * eva-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行列位置
 * nosource-source-map:錯誤和輸出資訊的準確位置,不可追溯到源代碼的行列位置
 * cheap-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行位置
 * cheap-module-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行列位置 會將webpack配置等資訊添加進來
*/

直接打包構建專案

專案結構
1)專案根目錄的控制臺執行指令:

webpack ./src/index.js -o ./build/built.js–mode=development,開發模式中打包src下的index.js入口檔案;輸出在build路徑下檔案名為built.js,

2)打包結果分析:

每次打包都會生成不重復且唯一的hash值,打包構建所用時間以及檔案的大小等引數,

構建結果

組態檔方式構建

專案跟目錄下建立webpack.config,js檔案,當我們控制臺輸入webpack打包指令時,默認會按webpack.config.js中的配置去打包構建,組態檔檔案通過commomjs的方式暴露一個配置物件,這個就不再分析了,具體看webpack.config.js檔案,

作業環境專案結構

webpack.config.js詳細配置

const { resolve } = require("path"); // 引入node.js的一個path路徑模塊,通過解構獲取到一個resolve屬性值,用于獲得當前目錄的絕對路徑,
const HtmlWebpackPlugin = require("html-webpack-plugin"); // 處理html插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 抽離css成單獨檔案插件
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin"); // 引入壓縮Css代碼插件
const WorkboxWebpackPlugin = require("workbox-webpack-plugin"); // 引入實作PWA離線快取技術插件
const TerserWebpackPlugin = require("terser-webpack-plugin"); // 壓縮js代碼插件
const webpack = require("webpack"); // 引入dll定義屬性插件,通過.json映射檔案實作忽略單獨打包的第三庫,在通過addAssetHtmlWebpackPlug進行單獨引入,
const addAssetHtmlWebpackPlugin = require("add-asset-html-webpack-plugin"); // dll單獨打包庫自動引入html插件

// process.env.NODE_ENV = "production"; // 設定nodejs的行程環境為production生成環境,postcss默認作業于生產環境下,
module.exports = {
  entry: "./src/main.js",
  /**
   * 陣列形式:陣列多入口,構建打包后形成一個chunk,一個js檔案,常用于將html檔案引入,使其具有HMR熱替換功能,
   * 物件形式:物件多入口形式,生成多個chunk,構建后形成多個js檔案,用于代碼分隔,
   */
  // entry: ["./src/index.js", "./src/test.js"]
  // entry: {
  //   index: "./src/index.js",
  //   test: ["./src/test.js"], // 特殊陣列寫法
  // },
  output: {
    filename: "static/js/[name].js",
    path: resolve(__dirname, "build"),
    chunkFilename: "js/[name]~[contenthash:10].js", // 通過懶加Es6懶加載方式和optimization插件進行分割形成的chunk遵循這個命名規則
    library: "[name]Lib", // 構建打包向外暴露名,即呼叫名,
    libraryTarget: "window", // 系結到window物件中,很多屬性物件,
  },
  module: {
    rules: [
      // eslint語法檢查
      {
        /**
         * js語法所需loader安裝指令:npm i eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import -D
         * eslint的js語法檢查是依托于airbnb規則進行檢查,根據package.json下的eslintConfig的配置進行檢測語法,
         * airbnb默認是不能認識window等物件,可通過eslintConfig下的env屬性進行屏蔽檢查,可通過eslint-disable-next-line注釋取消下一行的語法檢查,
         */
        test: /\.js$/, // 通過正則匹配后綴名為.js的檔案
        enforce: "pre", // 設定loader的執行順序,pre(優先)| post(延后),
        exclude: /node_modules/, // 排除node_modules目錄下js檔案的語法檢查
        loader: "eslint-loader", // 指定eslint-loader執行處理js檔案進行語法檢查
        options: {
          fix: true, // 配置參、空格、縮進不規范的語法自動進行修復,
        },
      },
      {
        // 當檔案流到這個物件時,匹配到一個規則之后就不再向下匹配,優化構建打包速度,
        oneOf: [
          {
            // 處理css檔案的規則所需loader安裝指令:npm i style-loader -D 和 npm i css-loader -D
            test: /\.css$/,
            // 處理檔案時使用到多個lorder時,執行順序為從下到上,
            use: [
              // "style-loader", // 處理創建style標簽,將js中處理的資源添加到style標簽中,再添加到頁面head中生效,
              {
                loader: MiniCssExtractPlugin.loader, // 因為css引入js檔案中,會造成js代碼檔案過大,所以通過MiniCssExtractPlugin建構式自帶loader取代style-loader,作用為將css抽離成為單個檔案通過link標簽引入,
                options: {
                  publicPath: "../../", // 資源引入html檔案時的路徑前綴,因為css檔案以及被單獨抽離至特定目錄下,正確修改才能匹配到css中參考的靜態資源,
                },
              },
              // 翻譯css使webpack能夠識別css樣式語法
              "css-loader",
              {
                loader: "postcss-loader", // 使用postcss進行瀏覽器兼容,使用的方法是在package.json中定義browserslist屬性規則進行瀏覽器兼容性語法補全,
                options: {
                  ident: "postcss",
                  plugins: () => [require("postcss-preset-env")],
                },
              },
            ],
          },
          {
            // 處理less檔案的規則所需loader安裝指令:npm i less-loader -D 和 npm i less -D
            test: /\.less$/,
            use: [
              // "style-loader",
              {
                loader: MiniCssExtractPlugin.loader,
                options: {
                  publicPath: "../../",
                },
              },
              "css-loader",
              "less-loader",
            ],
          },
          {
            // 處理圖片檔案的規則安裝指令:cnpm i url-loader file-loader  -D
            test: /\.(png|jpe?g|gif|gif|svg)(\?.*)?$/,
            loader: "url-loader",
            options: {
              limit: 80 * 1024, // 當圖片小于80kb時采用base64的方式打包,大于則以圖片形式打包,
              name: "[hash:10].[ext]", // 每次webpack構建打包會生成一串不重復的hash碼,[hash:10]則是去hash的前十位,[ext]取源檔案的后綴名,
              outputPath: "static/img", // 輸出目錄,output定義了輸出目錄為build,此處圖片輸出目錄為build/static/img/XXX檔案,
              esModule: false, // 默認使用es6語法決議,html-loader使用的是commonjs語法引入,但2020年09月24日不用關閉url-loader的es6決議方法,
            },
          },
          {
            // 處理html中img等標簽引入的圖片資源所需loader安裝指令:npm i html-loader  -D
            test: /\.html$/,
            loader: "html-loader", // 處理url-loader僅能處理打包圖片而不能處理html中資源的遺留問題,
          },
          {
            // 處理引入字體圖示資源所需loader安裝指令:npm install file-loader -D
            test: /(\.(ttf|woff|eot)$|iconfont\.svg)/,
            loader: "file-loader",
            options: {
              name: "[hash:10].[ext]",
              outputPath: "static/font",
            },
          },
          {
            /**
             * 處理es6語法轉es5語法和Promise等新增屬性所需的loader安裝指令:npm i babel-loader @babel/preset-env @babel/core @babel/polyfill core-js -D
             * 關于解決Promise等新增技術IE舊(垃)版(圾)瀏覽器不能識別的問題:
             * 1)入口檔案中首行添加import '@babel/polyfill' 引入模塊,簡單方便,但會引入不必要的兼容配置,造成代碼體積偏大,
             * 2)按需加載比較推薦
             */
            test: /\.js$/,
            exclude: /node_modules/,
            use: [
              {
                /**
                 * 開啟多行程打包所需loader安裝指令:npm install thread-loader -D
                 * 可以給每一個規則使用這個loader,但是建議只給js進行,因為js打包花費的時間很多,建議專案足夠大時打開多行程打包,開啟經常需要600ms,行程通信也有開銷,
                 */
                // ,
                loader: "thread-loader", // 建議專案足夠大時打開多行程打包,開啟經常需要600ms,行程通信也有開銷,
                options: {
                  works: 4, // 核數
                },
              },
              {
                loader: "babel-loader",
                options: {
                  presets: [
                    // "@babel/preset-env" // 把下面陣列的注釋掉不會適配Promise等高級技術了,僅僅會轉換let、const、箭頭函式,
                    [
                      "@babel/preset-env",
                      {
                        useBuiltIns: "usage",
                        corejs: {
                          version: 3,
                        },
                        // 兼容范圍
                        targets: {
                          chrome: "50",
                          firefox: "50",
                          ie: "10",
                          safari: "10",
                          edge: "18",
                        },
                      },
                    ],
                  ],
                  // 開啟JS代碼快取,當檔案名不變時,瀏覽器強制快取js檔案,導致修改的專案不能實時更新,所以應該在output中輸出檔案名中包含hash值,采用的是[content:10]的根據內容生成hash值的形式,沒有采用hash是因為css在js中引入屬于同一個chunk,輸出時帶有同一個hash值,
                  cacheDirectory: true,
                },
              },
            ],
          },
        ],
      },
    ],
  },
  // 插件使用需要先引入在new生成實體
  plugins: [
    // 無template屬性時,默認在輸出目錄創建一個空的html檔案,并將打包后的資源引入其中,template指明檔案時,則復制檔案,并引入打包后的資源,
    new HtmlWebpackPlugin({
      template: "./src/index.html",
      minify: {
        collapseWhitespace: true, // 清除空行縮進
        removeAttributeQuotes: true, // 清除注釋
      },
    }),
    // 處理CSS從js檔案中抽離生成獨立檔案
    new MiniCssExtractPlugin({
      filename: "static/css/app.css", // 檔案輸出目錄
    }),
    // Css壓縮插件
    new OptimizeCssAssetsWebpackPlugin(),

    // PWA離線快取技術,優化使用體驗,網路斷開后重繪網頁仍能夠加載得到已經快取的資源檔案,依靠service Workers技術,插件執行后生成一個servicework組態檔,需要在入口檔案中注冊,兼容性判斷,
    new WorkboxWebpackPlugin.GenerateSW({
      clientsClaim: true, // 幫助servicework快速啟動
      skipWaiting: true, // 洗掉舊版本使用最新的serviceworker技術
    }),

    /**
     * dll動態引入單獨庫
     * 通過manifest.json檔案中的映射關系,構建打包時進行忽略打包哪些庫,再通過addAssetHtmlWebpackPlugin引入獨立打包的庫,
     */
    new webpack.DllReferencePlugin({
      manifest: resolve(__dirname, "dll/manifest.json"),
    }),
    new addAssetHtmlWebpackPlugin({
      filepath: resolve(__dirname, "dll/jquery.js"),
    }),
  ],
  // mode: "development",
  mode: "production", // 設定webpack的作業環境

  // 打包構建忽略打包的庫,并通過手動外部CDN引入,
  // externals: {
  //   jquery: "jquery",
  // },

  /**
   * 安裝指令:npm i webpack-dev-server -D
   * 開發服務器自動編譯、自動重繪、自動打開瀏覽器,只會在記憶體中編譯打包,不會輸出代碼,本地安裝啟動指令:npx webpack-dev-server,
   */
  devServer: {
    contentBase: resolve(__dirname, "build"), // 運行代碼目錄
    watchContentBase: true, // 監視contentBase下檔案目錄,發現檔案變化則reload,
    watchOptions: {
      ignored: /node_modules/, // 忽略檔案
    },
    compress: true, // 采用gzip壓縮代碼體積會更小
    port: 9527,
    host: "localhost",
    open: true, // 自動打開瀏覽器
    hot: true, // 開啟HMR功能,提高開發環境打包的效率,
    clientLogLevel: "none", // 不需要開啟webpack啟動日志資訊
    quiet: true, // 僅僅顯示基本資訊
    overlay: true, // 不要全屏顯示報錯
    proxy: {
      "/api": {
        // 處于5000埠的devserver接收到/api的請求,會將請求代理轉發到3000埠下的服務,
        target: "http://localhost:3000/",
        // 去掉/api,路徑替換重寫為http://localhost:3000/檔案,
        pathRewrite: {
          "^/api": "",
        },
      },
    },
  },
  // 決議模塊
  resolve: {
    alias: {
      assets: resolve(__dirname, "src/assets/"), // 設定路徑別名
    },
    // extensions: ["js", "css", "vue", "json"], // 引入時可省略的后綴名
    modules: ["node_modules"],
  },
  // 將node_modules里面的庫單獨打包成一個檔案verdor.js,配置項太多了,官網自行查看,
  optimization: {
    splitChunks: {
      chunks: "all", // 所有配置均為默認
    },
    // 入口檔案打包的主構建檔案(main)需要參考其他的chunk,打包生成后main會存有其他chunk打包的hash值(使用contenthash方式命名),一旦其他chunk發生改動,main也需要重新打包構建,會造成快取失效,此配置將main檔案中記錄其他chunk的hash值打包成為一個單獨的檔案,再將此檔案引入main,達到解耦的效果,
    runtimeChunk: {
      name: (entrypoint) => `runtime-${entrypoint.name}`,
    },
    // 通過Terser壓縮js代碼
    minimizer: [
      new TerserWebpackPlugin({
        // 開啟快取
        cache: true,
        // 開啟多行程打包
        parallel: true,
        // 啟用sourceMap,否則會被壓縮掉,
        sourceMap: true,
      }),
    ],
  },
  /**
   * 引數
   * source-map:錯誤代碼的準確資訊和源代碼的錯誤位置 并且能夠匯出對應的源代碼
   * inline-source-map:列印輸出的檔案位置 可定位到源代碼的位置
   * hidden-source-map:列印輸出的是打包后的代碼 可定位到定位打包后的位置 不可以追溯到源代碼的位置
   * eva-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行列位置,
   * nosource-source-map:錯誤和輸出資訊的準確位置,不可追溯到源代碼的行列位置,
   * cheap-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行位置,
   * cheap-module-source-map:錯誤和輸出資訊的準確位置 可追溯到源代碼的行列位置 會將webpack配置等資訊添加進來
   */
  devtool: "source-map", // 構建后代碼到源代碼的有一種映射技術,js輸出目錄下回多出一個xxx.js.map檔案,如果構建代碼出錯了,通過映射關系能找到源代碼的位置,非常利于除錯代碼,但是也會造成代碼被盜用的安全性問題,
};

package.json詳細配置

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.11.6",
    "@babel/polyfill": "^7.11.5",
    "@babel/preset-env": "^7.11.5",
    "add-asset-html-webpack-plugin": "^3.1.3",
    "babel-loader": "^8.1.0",
    "core-js": "^3.6.5",
    "css-loader": "^4.3.0",
    "eslint": "^7.9.0",
    "eslint-config-airbnb-base": "^14.2.0",
    "eslint-loader": "^4.0.2",
    "eslint-plugin-import": "^2.22.0",
    "file-loader": "^6.1.0",
    "html-loader": "^1.3.1",
    "html-webpack-plugin": "^4.5.0",
    "jquery": "^3.5.1",
    "less": "^3.12.2",
    "less-loader": "^7.0.1",
    "mini-css-extract-plugin": "^0.11.2",
    "optimize-css-assets-webpack-plugin": "^5.0.4",
    "postcss-loader": "^3.0.0",
    "postcss-preset-env": "^6.7.0",
    "style-loader": "^1.2.1",
    "terser-webpack-plugin": "^4.2.2",
    "thread-loader": "^3.0.0",
    "url-loader": "^4.1.0",
    "webpack": "^4.44.2",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0",
    "workbox-webpack-plugin": "^5.1.4"
  },
  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
  "eslintConfig": {
    "extends": "airbnb-base",
    "env": {
      "brower": true
    }
  },
  "sideEffects": [
    "*.css"
  ]
}

寄語

一篇肝了好久的webpack,篇幅很長再加上個人理解可能會有瑕疵,希望大牛別噴,給出的詳細webpack.config.js檔案我也已經測驗過了,我寫了很詳細的注釋,希望能幫到大家!但是如果轉載的話希望大家也能注明一下出處!

支持

個人開發了一個資源網址導航網站,很多資源分享,vue專案第一次進會慢一些些,但是過后就很快了,涵蓋了生活的方方面面,認真逛逛絕對會有識訓,無廣告且有軟體分享,希望大家支持一下!n.huasenjio.top,如果進不出意外的話我會把這個開源給大家!大家的訪問也許對我就是一種鼓勵了,謝謝大家!
首頁
深度

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/148212.html

標籤:其他

上一篇:Grakn Forces 2020(ABCD)

下一篇:什么是JWT?為什么選擇JWT?如何在Spring Cloud Security集成使用?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more