webpack基礎配置詳解

webpack 基本配置

  1. webpack && webpack-cli

安裝:npm i webpack webpack-cli -D
描述:webpack核心模塊javascript

  1. webpack-dev-server

安裝:npm i webpack-dev-server -D
描述:此安裝包,安裝webpack本地服務css

Webpack Dev Server 本地服務

  1. webpack-dev-server 基礎配置

安裝:npm i webpack-dev-server -D
描述: 本地開發服務html

module.exports={
  devServer:{
    port:8088, //端口
    hot:true,//是否熱更新
    // 服務器將從哪一個目錄去查找內容文件
    contentBase:path.resovle(__dirname,'dist'),
  }
}
複製代碼
  1. webpack-dev-server 跨域代理

一、直接使用代理
二、刪除一些自定義的路徑
三、設置多個代理
四、對https網址轉發設置 secure:false
五、本身設置mock數據(設置中間件), before()和after()vue

module.exports={
  devSever:{
     // 1.直接使用後臺接口名 後臺:/api/user 請求: /api/user
    proxy:{
      "/api":"http://192.168.1.54:8001",
    },

    // 2.本身添加「api」並刪除 後臺:/user 請求: /api/user
    proxy:{
      "/api":{
        target:"http://192.168.1.54:8001",
        pathRewrite:{ //重寫路徑,將「/api」刪除
          "/api":""
        }
      },
    }

    //3.多個代理到一個
    proxy:[
      {
        context: ["/api", "/pps", "/login"],
        target: 'http://192.168.1.54:8001',
        changeOrigin: true,
        //若是須要轉發的網站是支持 https 的,那麼須要增長secure=false,來防止轉發失敗
        secure: false,
      }
    ],
  // 中間件
    before(app){
      app.get("/user",(req,res)=>{
        res.json({"name":"xie"})
      })
    }
  }
}
複製代碼

html 處理

  1. html-webpack-plugin

安裝:npm i html-webpack-plugin -D
描述:此插件將html文件輸出在輸出文件夾中。主要參數具體解釋java

const HtmlWebpackPlugin = require("html-webpack-plugin ")
module.exports={
  plugins:[
    new HtmlWebpackPlugin({
      // html模板,能夠是 html, jade, ejs, hbs等,必須安裝對應的 loader
      template:"./index.html" ,
      filename: "index.html",
      //生成一個icon圖標
      favicon: "./favicon.ico",
      //hash值
      hash: true,
      // 使用的代碼塊,用於多文件打包
      chunks:["home","other"],
      //設置頁面的title
      title: 'webpackdemo'
      //minify壓縮
      minify: {
        //是否對大小寫敏感,默認false
        caseSensitive: true,

        //是否簡寫boolean格式的屬性
        //如:disabled="disabled" 簡寫爲disabled 默認false
        collapseBooleanAttributes: true,

        //是否去除空格,默認false
        collapseWhitespace: true,

        //是否壓縮html裏的css(使用clean-css進行的壓縮) 默認值false;
        minifyCSS: true,

        //是否壓縮html裏的js(使用uglify-js進行的壓縮)
        minifyJS: true,

        //Prevents the escaping of the values of attributes
        preventAttributesEscaping: true,

        //是否移除屬性的引號 默認false
        removeAttributeQuotes: true,

        //是否移除註釋 默認false
        removeComments: true,

        //從腳本和樣式刪除的註釋 默認false
        removeCommentsFromCDATA: true,

        //是否刪除空屬性,默認false
        removeEmptyAttributes: true,

        // 若開啓此項,生成的html中沒有 body 和 head,html也未閉合
        removeOptionalTags: false,

        //刪除多餘的屬性
        removeRedundantAttributes: true,

        //刪除script的類型屬性
        //在h5下面script的type默認值:text/javascript 默認值false
        removeScriptTypeAttributes: true,

        //刪除style的類型屬性, type="text/css" 同上
        removeStyleLinkTypeAttributes: true,

        //使用短的文檔類型,默認false
        useShortDoctype: true,
      }
    })
  ]
}
複製代碼
  1. 使用模板引擎 ejs

安裝:npm i html-loader ejs ejs-html-laoder -D
描述:一、安裝html-loader , 將html中的文件進行解析
二、安裝ejs、ejs-html-laoder對ejs模板進行解析node

//webpack.config.js
module.exports={
  plugins:[
    new HtmlWebpackPlugin({
      template: './index.ejs', // ejs模板
      filename: "index.html",
    }),
  ],
  module:{
    rules:[
      //處理ejs文件
      {
        test: /\.ejs$/,
        use: ['html-loader', 'ejs-html-loader', ]
      }
    ]
  }
}
複製代碼
  1. 多頁面處理 glob

安裝:npm i glob -D
描述:一、插件,匹配解析當前文檔目錄
二、多頁面DEMO:MultipleDemoreact

const glob = require('glob'); 

let setMAP = () => {
  const entry = {}; 
  const HtmlWebpackPlugins = []; 
  //獲取當前目錄下匹配 "./src/*/index.js" 的文件目錄
  const entryFiles = glob.sync(path.join(__dirname, "./src/*/index.js")); 
  entryFiles.forEach(v => {
    const Match = v.match(/src\/(.*)\/index\.js/);
    const pageName = Match && Match[1];
    entry[pageName] = v; //設置entry
    //設置多個html插件
    HtmlWebpackPlugins.push(
      new HtmlWebpackPlugin({
        template: v.replace('index.js', 'index.html'),
        filename: `${pageName}/${pageName}.html` ,
        chunks: [pageName],
        favicon: path.resolve(__dirname, "favicon.ico"), //生成一個icon圖標
      })
    );
  })
  return {
    entry,
    HtmlWebpackPlugins
  }
}
const {entry, HtmlWebpackPlugins} = setMAP(); 

module.exports={
  entry:entry, 
  plugins:[....].contact(HtmlWebpackPlugins)
}
複製代碼

css 處理

  1. css-loader

安裝:npm i css-loader -D
描述:一、此loader 對 css 中的 @import進行處理
二、內部集成了 cssnanojquery

//js中內聯處理
import css from 'css-loader!./css/index.css';
console.log(css);
複製代碼
  1. mini-css-extract-plugin (經常使用)

安裝:npm i mini-css-extract-plugin -D
描述:一、插件, 將全部的css樣式打包在一個文件中,經過 link引入。
二、在loader 中使用 MiniCssExtractPlugin.loaderwebpack

  1. style-loader (可選)

安裝:npm i style-loader -D
描述:一、此loader 將css插入到html中
二、與 mini-css-extract-plugin 不能共用git

  1. postcss-loader && autoprefixer

安裝:npm i postcss-loader autoprefixer -D
描述:一、此插件和loader是自動給css樣式添加瀏覽器前綴。
二、在webpack.config.js中配置 引入 autoprefixer
三、在package.json文件中配置。
四、在根目錄建立 postcss.config.js 文件。
五、配置 package.json 中的browserslist來傳遞autoprefixer的參數。

// package 內容
{
  ....
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

// postcss.config.js 內容
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}
複製代碼

案例:

const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 

module.exports={
  plugins:[
    new MiniCssExtractPlugin({
      filename: "main.[hash:8].css",
      // hash: true
    })
  ]
  module:{
    rules:[{
      test:/\.css$/,
      use:[
        MiniCssExtractPlugin.loader,
        "css-loader",
        {
          //也能夠在package.json中引入autoprefixer插件
          loader: "postcss-loader",
          options: {
            plugins: [require('autoprefixer')({
              //傳參,將覆蓋package.json中的"browserslist"
              //並不推薦這樣寫。應寫在package.json中"browserslist"
              overrideBrowserslist: ["last 2 version"]
            })]
          }
        },
      ]
    }]
  }
}
複製代碼
  1. node-sass && sass-loader 、less && less-loader、stylus && stylus-loader

安裝:npm i node-sass sass-loader -D
描述:此loader 將scss/less/stylus 進行 =>css 處理
Tips:fast-sass-loader 比 sass-loader快5-10倍

  1. optimize-css-assets-webpack-plugin

安裝:npm i optimize-css-assets-webpack-plugin -D
描述:一、此插件是將css代碼進行壓縮。使用此插件,須要js插件進行js壓縮。
二、在 optimization 中寫。

optimization: {
    minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
  },
複製代碼

JS 處理

  1. @babel/core

安裝:npm i @babel/core -D
描述:插件,將es語法轉換爲經常使用的js語法

  1. babel-loader

安裝:npm i babel-loader -D
描述:此loader 是 babel 轉換的loader

  1. @babel/preset-env

安裝:npm i @babel/preset-env -D
描述:babel 預設環境

  1. @babel/plugin-transform-runtime && @babel/runtime(生產環境)

安裝:npm i @babel/plugin-transform-runtime -D
安裝:npm i @babel/runtime -S
描述:一、babel插件 , ES代碼裝換時,能夠重複使用Babel注入的幫助程序代碼來節省代碼。
二、對於實例方法,例如"foobar".includes("foo")只能使用core-js

  1. @babel/runtime-corejs2 || @babel/runtime-corejs3 (生產環境)

安裝:npm i @babel/runtime-corejs2 -S
安裝:npm i @babel/runtime-corejs3 -S
描述:補充對於實例方法的不支持

["@babel/plugin-transform-runtime", {corejs: 3}]

//babel
{
  test: /\.js$/,
  use: [{
    loader: "babel-loader",
    options: {
      presets: ['@babel/preset-env'],
      plugins: [
        ["@babel/plugin-proposal-decorators", {
          "legacy": true
        }],
        ["@babel/plugin-proposal-class-properties", {
          "loose": true
        }],
        ['@babel/plugin-transform-runtime', {
          corejs: 3
        }]
      ]
    },
    env: { //根據不一樣環境配置不一樣不一樣參數
      production: {
        "presets": ["@babel/preset-env"]
      }
    }
  }],
  include: path.resolve(__dirname, 'src'), // 包含路徑
  exclude: /node_modules/ // 排除路徑
}
複製代碼
  1. @babel/polyfill (生產環境)(babel7.4.0已廢棄)(可以使用corejs)

安裝:npm i @babel/polyfill -D
描述:babel插件 , 將實例方法進行解析,在babel7.4.0已廢棄,可使用第7條corejs

npm install --save @babel/polyfill
// 在index.js中引入便可
require("@babel/polyfill")
複製代碼
  1. @babel/plugin-proposal-class-properties

安裝:npm i @babel/plugin-proposal-class-properties -D
描述:babel插件 , 對es 中 class 模塊進行轉換

  1. @babel/plugin-proposal-decorators

安裝:npm i @babel/plugin-proposal-decorators -D
描述:babel插件 , 裝飾器

module: {
  rules: [
    //babel 轉換
    {
      test: /\.js$/,
      use: [{
        loader: "babel-loader",
        options: {
          presets: ['@babel/preset-env'],
          plugins: [
            ["@babel/plugin-proposal-decorators", {
              "legacy": true
            }],
            ["@babel/plugin-proposal-class-properties", {
              "loose": true
            }]
          ]
        }
      }]
    }
  ]
}
複製代碼
  1. eslint && eslint-loader

安裝:npm i eslint eslint-loader -D
描述:一、js校驗。須要配置文件 .eslintrc.json
二、ESLint 的報錯類型包括三種:off、warn和error,分別對應着:0、一、2
三、配置.eslintrc.jsoneslint.org/demo
四、規則說明:中文英文
五、騰訊 Alloy規則:Github

// .eslintrc.json
{
  "extends": ['alloy',], //使用本身安裝的規則
  'rules': { //本身配置規則
      // 禁止 console,要用寫 eslint disbale
      'no-console': 2,
      // 禁止 debugger,防止上線
      'no-debugger': 2,
  }
}

//webpack.config.js
module: {
  rules: [
    //ESLINT
    {
      test: /\.js$/,
      use: {
        loader: "eslint-loader",
        options: {
          enforce: 'pre'  //pre:以前 , post:以後
        }
      }
    }
  ]
}
// package.json
{
  "name":"",
  "eslintConfig": {
    "extends": [],
    "rules": {
      'no-console': 2,
    },
},
}
複製代碼

圖片引入打包

  1. file-loader (大圖片,必須) && url-loader(圖片轉化base64)

loader , 對於引入的文件處理

module.exports={
  module:{
    rules:[
      {
        test:/\.(png|jpg|jpeg|gif)$/,
        //當圖片小於多少k時,轉爲base64,不然使用file-loader導出
       // use:'file-loader'
       use:{
         loader:'url-loader',
         options:{
           limit:200*1024 //200k
         }
       }
      }
    ]
  }
}
複製代碼
  1. 使用js引入圖片
import logo from "./logo.jpg"
  let img = new Image()
  img.src = logo;
 //或者 img.src = require('./logo.jpg');
  document.body.appendChild(img)
複製代碼
  1. 使用css引入圖片

一、直接引入,由於css-loader會進行轉換
二、css中使用 alias配置的參數,須要加上 ~

background:url('./logo.jpg')  => background:url(rquire('./logo.jpg'))
複製代碼
  1. 使用html引入圖片 html-loader

描述:一、loader,對html中的外部資源(圖片等)進行轉換

rules:[
  {
    test:/\.html$/,
    use:'html-loader'
  }
]
複製代碼

三、htmlcss中使用 alias配置的參數,須要加上 ~

// webpack.config.js
const path = require('path')
module.exports={
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')
    }
  }
}
//html 
<img src="~@/img/large.png" alt="背景圖" />
//css
.bg-img {
    background: url(~@/img/small.png) no-repeat;
}
複製代碼

其餘資源處理

  1. 字體、富媒體

對於字體、富媒體等靜態資源,能夠直接使用url-loader或者file-loader進行配置便可

{
    // 文件解析
    test: /\.(eot|woff|ttf|woff2|appcache|mp4|pdf)(\?|$)/,
    loader: 'file-loader',
    query: {
        // 這麼多文件,ext不一樣,因此須要使用[ext]
        name: 'assets/[name].[hash:7].[ext]'
    }
},
複製代碼

打包文件分類

  1. 設置全局路徑 publicPath

對於引入的資源(js, css, images等)都將會自動加上 publicPath

module.exports={
  output:{
    filename: "bunlde.[hash:8].js",
    path: path.resolve(__dirname, 'dist'), // 當前目錄下的dist
    publicPath:'https://www.baidu.com'
  }
}
複製代碼
  1. 設置css打包文件夾名

MiniCssExtractPlugin 插件中filename里加 css/

module.exports={
  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/main.[hash:8].css", // 添加css/
    })
  ], 
}
複製代碼
  1. 設置圖片打包文件夾名

一、在 url-laoder(file-loader)中的options裏設置 outputPath
二、也能夠單獨設置一個publicPath

rules: [
  // 圖片引入
  {
    test: /\.(png|jpg|jpeg|gif)$/,
    //當圖片小於多少k時,轉爲base64,不然使用file-loader導出
    // use:'file-loader'
    use: {
      loader: 'url-loader',
      options: {
        limit: 200 * 1024, //200k
        outputPath: "img/",
        // publicPath:"https://xxx.xie.com"
      }
    }
  }
]
複製代碼

webpack 小插件

  1. clean-webpack-plugin

安裝:npm i clean-webpack-plugin -D
描述:一、在打包時將以前的文件夾清理掉
二、clean-webpack-plugin升級踩坑

const {CleanWebpackPlugin} = require('clean-webpack-plugin') // 新版須要進行解構
module.exports={
  plugins: [
    new CleanWebpackPlugin() //默認不傳參數,將會刪除output指定的輸出文件夾
    //傳參
    new CleanWebpackPlugin({
      // 忽略掉不須要刪除的文件,至關於exclude,被忽略的文件須要在開頭加上 "!"號
      // 數組中必須帶有"**/*"通配符,不然dist下的文件都不會被刪除
      // 刪除指定文件/文件夾 path.resolve(__dirname, 'test6')
      cleanOnceBeforeBuildPatterns: ["**/*", path.resolve(__dirname, 'build'),"!public"]
    })
  ]
}
複製代碼
  1. copy-webpack-plugin

安裝:npm i copy-webpack-plugin -D
描述:將文件拷貝到新的地方,一般用做將靜態資源拷貝到dist文件夾中

const CopyWebpackPlugin = require("copy-webpack-plugin")
module.exports={
  plugins: [
    //裏面放置數組,能夠填寫多個
    // 默認會放到output中指定的輸出文件夾
    new CopyWebpackPlugin([{
      from: "./src/vendor",
      to: "vendor"
    }])
  ]
}
複製代碼
  1. BannerPlugin

webpack自帶插件,將每一個問價中寫入版權信息

const webpack = require('webpack')
module.exports={
  plugins: [
    new webpack.BannerPlugin('make 2019 by joannes')
  ]
}
複製代碼

resolve 參數

  1. resolve.alias

經常使用,文件名縮寫

module.exports={
  resolve:{
    alias:{
      //解析路徑
      "@":path.resolve(__dirname, 'src')
    }
  }
}
複製代碼
  1. resolve.extensions

幫助 Webpack 解析擴展名的配置,默認值:['.wasm', '.mjs', '.js', '.json']

module.exports = {
  resolve: {
      extensions: ['.js', '.json', '.css']
  }
}; 
複製代碼
  1. 其餘參數
resolve.mainFields: 入口字段  
resolve.mainFiles:解析目錄時候的默認文件名,默認是index,即查找目錄下面的index+resolve.extensions文件  
resolve.modules:查找模塊依賴時,默認是node_modules  
resolve.symlinks:是否解析符合連接(軟鏈接,symlink)  
resolve.plugins:添加解析插件,數組格式  
resolve.cachePredicate:是否緩存,支持 boolean 和 functionfunction 傳入一個帶有 pathrequire 的對象,必須返回 boolean 值。 複製代碼

區分不一樣環境

  1. process.env.NODE_ENV

一、設置mode將會默認設置 process.env.NODE_ENV

module.exports={
  mode:'production', // process.env.NODE_ENV=production
  mode:'development' // process.env.NODE_ENV=development
}
複製代碼

二、cross-env 設置 process.evn.NODE_ENV
安裝: npm i cross-env -D

// package.json
{
  "scripts": {
      "build": "cross-env NODE_ENV=production webpack --config webpack.config.js"
  }
}
複製代碼
  1. 設置環境變量, webpack.DefinePlugin
new webpack.DefinePlugin({
    ENV: JSON.stringify('dev')
  })
複製代碼
  1. 設置不一樣開發環境config webpack-merge

安裝:npm i webpack-merge -D
描述:一、安裝 webpack-merge
二、設置一個公共的參數,例如:webpack.base.js
三、分別設置不一樣環境的參數,例如:webapck.prod.js,webpack.dev.js
四、在不一樣的環境中引入公共參數和webpakc-merge
五、在package.json中設置不一樣的啓動命令

//package.json
"scripts": {
  "build": "webpack --progress --config webpack.prod.js", 
  "dev": "webpack-dev-server --progress --config webpack.dev.js"
}
// webpack.prod.js
let {smart} = require('webpack-merge')
let base = require("./webpack.base.js")
module.exports = smart(base, {
  mode: "production", 
})
複製代碼

全局變量引入(jquery爲例)

默認已經經過npm安裝了jQuery

  1. import $ from "jquery"

在須要的js文件中直接引入, 可是不能夠用 window.$

  1. expose-loader (生產環境)

安裝:npm i expose-loader -S
描述:一、暴露全局的loader
二、pre: 前置 , normal: 正常 , expose-loader: 內聯 , post: 後置

//使用一:在文件中使用
import $ from "expose-loader?$!jquery"

//使用二:在webpack.config中配置
module:{
  rules:[
    {
      test:require.resovle('jquery'), //匹配引入jQuery
      user:"expose-loader?$"
    }
  ]
},
import $ from "jquery" 
複製代碼
  1. webpack.ProvidePlugin

webpack自帶插件,將 $ 注入到每一個模塊中

//在webpack.config中配置
const webpack = require('webpack')
module.exports={
  plugins:[
   new webpack.ProvidePlguin({
     $:'jquery'
   })
  ]
}
複製代碼
  1. externals 忽略引入

忽略引入,不進行打包, jquery已經經過cdn引入了

module.exports={
  externals:{
    jquery:'$'
  }
}
複製代碼

devtool 調試代碼

  1. source-map

源碼映射,單獨生成一個sourcemap文件,報錯時會標識當前報錯的列和行

module.exports={
  entry:'', 
  devtool:"source-map"
}
複製代碼
  1. eval-source-map

源碼映射,不會產生單獨文件,報錯時會標識當前報錯的列和行

module.exports={
  entry:'', 
  devtool:"eval-source-map"
}
複製代碼
  1. cheap-module-source-map

源碼映射,單獨生成一個sourcemap文件,報錯時不會標識當前報錯的列和行

module.exports={
  entry:'', 
  devtool:"cheap-module-source-map"
}
複製代碼
  1. cheap-module-eval-source-map

源碼映射,不會產生單獨文件,報錯時不會標識當前報錯的列和行

module.exports={
  entry:'', 
  devtool:"cheap-module-eval-source-map"
}
複製代碼

watch 實時監控打包

  1. watch

將watch設置爲 true時,將會實時監控文件

  1. watchOptions

設置watch相關參數

module.exports={
  entry:'', 
  watch:true, 
  watchOptions:{
    poll:1000, // 每秒問我 1000 次
    aggregateTimeout:500, // 防抖
    ingored: /node_modules/  //不須要監控的文件
  }
}
複製代碼

webpack優化 -- 體積優化

  1. javascript壓縮
    1.一、terser-webpack-plugin

    安裝:npm i terser-webpack-plugin -D
    描述:webpack官方維護的js壓縮插件

    const TerserPlugin = require('terser-webpack-plugin');
    module.exports = {
        optimization: {
            minimizer: [
              new TerserPlugin({
                parallel: true,  // 多線程
                // 使用 cache,加快二次構建速度
                cache: true,
                terserOptions: {
                    comments: false,
                    compress: {
                        // 刪除無用的代碼
                        unused: true,
                        // 刪掉 debugger
                        drop_debugger: true, 
                        // 移除 console
                        drop_console: true, 
                        // 移除無用的代碼
                        dead_code: true 
                    }
                }
              });
            ]
        }
    };
    複製代碼
    1.二、Scope Hoisting

    描述:一、做用域提高。webpack分析模塊關係,儘量把模塊放到一個函數中
    二、致使打包的文件體積比較大

    // webpack.config.js
      module.exports = {
          optimization: {
              concatenateModules: true //設置
          }
      };
    複製代碼
  2. CSS體積優化
    2.一、mini-css-extract-plugin

    安裝:npm i mini-css-extract-plugin -D
    描述:將css打包成一個文件再引入

    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    module.exports = {
      plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: '[name].[contenthash:8].css'
        })
      ],
      module: {
        rules: [
          {
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader'
            ]
          }
        ]
      }
    };
    複製代碼
    2.二、optimize-css-assets-webpack-plugin

    安裝:npm i optimize-css-assets-webpack-plugin -D
    描述:css壓縮插件。使用的是cssnano引擎

    // webpack.config.js
    const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    module.exports = {
      optimization: {
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
      }
    };
    複製代碼
  3. 圖片資源優化

一、使用file-loader或者url-loader
二、參考上面的圖片引入

webpack優化 -- 拆分代碼

  1. splitChunks常見配置

一、使用optimization 中的 splitChunks
二、詳細解釋地址

module.exports = {
    // ...
    optimization: {
        splitChunks: {
            chunks: 'async', // 三選一: "initial" | "all" | "async" (默認)
            minSize: 30000, // 最小尺寸,30K,development 下是10k
            maxSize: 0, // 文件的最大尺寸,0爲不限制
            minChunks: 1, // 默認1,被提取的一個模塊至少須要在幾個 chunk 中被引用
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/, // 正則規則,若是符合就提取 chunk
                    priority: -10 // 緩存組優先級,當一個模塊可能屬於多個 chunkGroup,這裏是優先級
                },
                default: {
                    minChunks: 2,
                    priority: -20, // 優先級
                    reuseExistingChunk: true // 若是該chunk包含的modules都已經另外一個被分割的chunk中存在,那麼直接引用已存在的chunk,不會再從新產生一個
                }
            }
        }
    }
};
複製代碼
  1. cacheGroups緩存組

一、splitChunks的配置項都做用於cacheGroup上的,默認有兩個cacheGroup:vendorsdefault 二、獨有的配置項:test(匹配規則)、priority(優先級)和reuseExistingChunk (複用)

webpack優化 -- 速度優化

  1. 減小查找過程
    1.一、resolve.alias

    別名,快速查找

    module.exports={
      resolve:{
        alias:{
          "@":path.resolve(__dirname,'src')
        },
        extensions:['js','json','vue']
      }
    }
    複製代碼

    1.二、resolve.extensions

    一、優先查找,將優先查找定義後綴的文件
    二、或者引入文件帶上後綴名

    1.三、noParse

    一、排除不須要解析的模塊 二、或者引入文件帶上後綴名

    module.exports={
      module:{
        noParse: /node_modules\/(jquey\.js)/;
        rules: [
          {
            // test 使用正則
            test: /\.js$/,
            loader: 'babel-loader',
            // 排除路徑使用數組
            exclude: [path.resolve(__dirname, './node_modules')],
            // 查找路徑使用數組
            include: [path.resolve(__dirname, './src')]
          }
        ];
      },
    }
    複製代碼

    1.四、rules配置

    一、只在 test 和 文件名匹配中使用正則表達式
    二、在 include 和 exclude 中使用絕對路徑數組;
    三、儘可能避免 exclude,更傾向於使用 include

  2. happypack 多線程打包

安裝:npm i happypack -D
描述:happypack插件 ,多線程打包

const Happypack = require('happypack')
module.exports = {
  plugins: [
    new Happypack({
      id: 'js',
      use: [{
        loader: "babel-loader",
        options: {
          presets: ['@babel/preset-env'],
          plugins: [
            ["@babel/plugin-transform-runtime", {
              corejs: 3
            }]
          ]
        }
      }]
    })
  ], 
  module: {
    // css一樣適用
    rules: [{
      test: /\.js$/,
      use: "Happypack/loader?id=js",
      exclude: /node_modules/
    }]
  }
}
複製代碼
  1. webpack.DllPlugin 來預先編譯
    3.一、DLLPlugin

    一、須要單獨設置一個獨立的webpack配置文件.例:webpack.config.dll.js

    // webpack.config.dll.js
    const webpack = require('webpack');
    // 這裏是第三方依賴庫
    const vendors = ['react', 'react-dom'];
    
    module.exports = {
        mode: 'production',
        entry: {
            // 定義程序中打包公共文件的入口文件vendor.js
            vendor: vendors
        },
        output: {
            filename: '[name].[chunkhash].js',
            // 這裏是使用將 verdor 做爲 library 導出,而且指定全局變量名字是[name]_[chunkhash]
            library: '[name]_[chunkhash]'
        },
        plugins: [
            new webpack.DllPlugin({
                // 這裏是設置 mainifest.json 路徑
                path: 'manifest.json',
                name: '[name]_[chunkhash]',
                context: __dirname
            })
        ]
    };
    複製代碼
    3.二、DllReferencePlugin

    webpack.config.js中指定manifest.json的內容

    // webpack.config.js
    const webpack = require('webpack');
    module.exports = {
        output: {
            filename: '[name].[chunkhash].js'
        },
        entry: {
            app: './src/index.js'
        },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                // 這裏導入 manifest配置內容
                manifest: require('./manifest.json')
            })
        ]
    };
    複製代碼

webpack優化 -- 其餘優化

  1. IgnorePlugin

webpack自帶插件,設置忽略某項引入

plugins: [
    //忽略引入 ./locale 在moment中
    new webpack.IgnorePlugin(/\.\/locale/,/moment/)
  ], 
  // 能夠手動引入所需的語言包
  import "moment/locale/zh-cn"; 
  moment.locale("zh-cn"); 
複製代碼
  1. webpack內置優化

一、tree-shaking

使用 import 導入時,在打包時會自動去除沒用的代碼
require導入是放在一個對象中的,且不會去除代碼, 在default中

二、scope-hosting

做用域提高,打包時將多餘的變量進行轉化

  1. @babel/plugin-syntax-dynamic-import import按需懶加載

安裝:npm i @babel/plugin-syntax-dynamic-import -D
描述:babel插件,須要寫在babel中

// index.js
let button = document.createElement('button')
button.innerHTML = "name"
button.addEventListener('click', () => {
  import('./loader').then((data) => {
    console.log(data.default)
  })
})
document.body.appendChild(button)

//webpack.config.js
module.exports={
  module: {
    rules: [{
      test: /\.js$/,
      use: {
        loader: "babel-loader",
        options: {
          presets: ['@babel/preset-env'],
          plugins: [
            ["@babel/plugin-transform-runtime", {
              corejs: 3
            }],
            //引入
            ['@babel/plugin-syntax-dynamic-import']
          ]
        }
      },
      exclude: /node_modules/
    }]
  }
}

複製代碼
  1. 熱更新 HotModuleReplacementPlugin

webpack自帶插件, 須要在本地服務啓動 hot:true

module.exports={
  devSever:{
    hot:true
  }, 
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ], 
}
//index.js
import str from "./source"
if(module.hot){
  module.hot.accept('./source', ()=>{
    console.log("文件更新了")
  })
}
複製代碼

webpack經常使用插件,附表:Plugins

webpack經常使用loader,附表:Loaders

相關文章
相關標籤/搜索