webpack學(xué)習(xí)筆記

一、Webpack簡介

Webpack是一種前端資源構(gòu)建工具占遥,一個(gè)靜態(tài)模塊打包器瓦胎。
在webpack 看來, 前端的所有資源文件(js/json/css/img/less/...)都會(huì)作為模塊處理。
它將根據(jù)模塊的依賴關(guān)系進(jìn)行靜態(tài)分析负芋,打包生成對(duì)應(yīng)的靜態(tài)資源(bundle)旧蛾。

1.1核心概念

Entry

入口指示W(wǎng)ebpack以哪個(gè)文件為入口起點(diǎn)開始打包蚜点,分析內(nèi)部依賴绍绘。

Output

輸出指示W(wǎng)ebpack打包后的資源bundles輸出到哪里去厂镇。

Loader

Loader讓W(xué)ebpack能夠去處理那些非js文件捺信。

Plugins

插件可以用于執(zhí)行范圍更廣的任務(wù)迄靠。從打包優(yōu)化和壓縮到重新定義環(huán)境中的變量等。

Mode

(1) development 能讓代碼本地調(diào)試運(yùn)行的環(huán)境
源代碼→webpack(打包吠式、自動(dòng)化)→bundle
(2) production 能讓代碼優(yōu)化上線運(yùn)行的環(huán)境(要做的事多特占,拖累開發(fā)環(huán)境的構(gòu)建速度是目,打包慢)
css→js(大,閃) 提取出css;壓縮萍倡;兼容...

1.2運(yùn)行指令:

開發(fā)環(huán)境:webpack .src/index.js -o ./build --mode=development
    webpack會(huì)以 ./src/index.js 為入口文件開始打包列敲,然后輸出到 ./build/built.js,整體打包環(huán)境是開發(fā)環(huán)境
生產(chǎn)環(huán)境:webpack .src/index.js -o ./build --mode=production
  • 結(jié)論:
    1. webpack能處理js/json資源戴而,不能處理css/img等其他資源凑术。
    2. 生產(chǎn)環(huán)境和開發(fā)環(huán)境將ES6模塊化編譯成瀏覽器能識(shí)別的模塊化。
    3. 生產(chǎn)環(huán)境比開發(fā)環(huán)境多一個(gè)壓縮js代碼所意。

二淮逊、配置

2.1 開發(fā)環(huán)境配置

2.1.1 打包樣式資源

webpack.config.js

/* 
  webpack的配置文件
    作用:指示webpack干哪些活(當(dāng)運(yùn)行webpack指令時(shí)會(huì)加載里面的配置)
*/

// resolve用來拼接絕對(duì)路徑的方法
const { resolve } = require('path')

module.exports = {
  // webpack配置
  // 入口起點(diǎn)
  entry: './src/index.js',

  // 輸出
  output: {
    // 輸出文件名
    filename: 'built.js',
    // 輸出路徑
    // __dirname 表示當(dāng)前文件目錄的絕對(duì)路徑
    path: resolve(__dirname, 'build')
  },

  // loader配置
  module: {
    rules: [
      {
        // 匹配哪些文件
        test: /\.css$/,
        // 使用哪些loader
        use: [
          // use數(shù)組中l(wèi)oader執(zhí)行順序:從右到左,從下到上
          // 創(chuàng)建style標(biāo)簽扶踊,將js中的樣式資源插入進(jìn)行,添加到head中生效
          'style-loader',
          // 將css文件變成commonjs模塊加載js中秧耗,里面的內(nèi)容是樣式字符串
          'css-loader'
        ]
      }
    ]
  },

  // plugins配置
  plugins: [

  ],

  // 模式
  mode: 'development'
  //mode: 'production'
}

2.1.2 打包html資源

webpack.config.js

/* 
  loader: 1. 下載 2. 使用
  plugin: 1. 下載 2. 引入 3. 使用
*/
const { resolve } = require('path')
//引入plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [

    ]
  },
  plugins:[
    // 功能:默認(rèn)創(chuàng)建一個(gè)空的html备籽,自動(dòng)引入打包輸出的所有資源
    // 需要:需要有結(jié)構(gòu)的html文件
    new HtmlWebpackPlugin({
      // 復(fù)制'./src/index.html‘文件,并自動(dòng)引入打包輸出的所有資源
      template: './src/index.html'
    })
  ],
  mode: 'development'
}

2.1.3 打包圖片資源

webpack.config.js

const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build'),
    publicPath: './'

  },
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'less-loader'
        ]
      },
      // 處理圖片資源
      {
        // 問題:處理不了html中的圖片
        test: /\.(JPG|png|gif)$/,
        // 使用一個(gè)loader
        // 下載url-loader file-loader
        loader: 'url-loader',
        options: {
          // 圖片大小小于8kb就會(huì)被base64處理
          // 優(yōu)點(diǎn):減少請(qǐng)求數(shù)量(減輕服務(wù)器壓力)
          // 缺點(diǎn):圖片體積變大(文件請(qǐng)求速度變慢)
          limit: 8 * 1024,
          // 問題:因?yàn)閡rl-loader默認(rèn)使用es6模塊化解析分井,而html-loader引入圖片是commonjs
          // 解決:關(guān)閉url-loader的es6模塊化车猬,使用commonjs解析
          esModule: false,
          // 圖片重命名
          // [hash:10]取圖片的hash前十位
          // [ext]取文件原擴(kuò)展名
          name: '[hash:10].[ext]'
        }
      },
      {
        test: /\.html$/,
        // 處理html文件的圖片(負(fù)責(zé)引入圖片,從而能被url-loader處理)
        loader: 'html-withimg-loader'
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
}

2.1.4 打包其他資源

webpack.config.js

const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      // 打包其他資源
      {
        // 排除css/js/html資源
        exclude: /\.(css|js|html|less)$/,
        loader: 'file-loader',
        options: {
          name: '[hash:10].[ext]'
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
}

2.1.5 開發(fā)服務(wù)器devServer

用來自動(dòng)化(自動(dòng)編譯尺锚,自動(dòng)打開瀏覽器珠闰,自動(dòng)刷新瀏覽器。缩麸。铸磅。)
特點(diǎn):只會(huì)在內(nèi)存中編譯打包,不會(huì)有任何輸出

devServer: {
  contentBase: resolve(__dirname, 'build'),
  // 啟動(dòng)gzip壓縮
  compress: true,
  port: 3000,
  // 自動(dòng)打開瀏覽器
  open: true
}

2.2 生產(chǎn)環(huán)境配置

2.2.1 提取css成單獨(dú)文件

MiniCssExtractPlugin

module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // 'style-loader',
          MiniCssExtractPlugin.loader,
          'css-loader'
        ]
      }
    ],
  },

2.2.2 css兼容性處理

postcss --> postcss-loader postcss-preset-env

const HtmlWebpackPlugin = require('html-webpack-plugin')
const { resolve } = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')


// 設(shè)置nodejs環(huán)境變量
// process.env.NODE_ENV = 'development'

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build'),
    publicPath: '/'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // 'style-loader',
          MiniCssExtractPlugin.loader,
          'css-loader',
          /* 
            css兼容性處理:postcss --> post-loader postcss-preset

            幫postcss找到package.json中的browserslist里面的配置杭朱,通過配置加載指定的css兼容性樣式
            "browserslist": {
              // 開發(fā)環(huán)境 --> 設(shè)置環(huán)境變量:process.env.NODE_ENV = development
              "development": [
                "last 1 chrome version"
              ],
              // 生產(chǎn)環(huán)境(默認(rèn))
              "production": [
                ">0.2%",
                "not dead",
                "not op_mini all"
              ]
            }
          */
          // 1. 使用loader的默認(rèn)配置
          // 'postcss-loader',
          // 2. 修改loader的配置
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [ require('postcss-preset-env')() ]
              }
            }
          }
        ]
      }
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/built.css'
    })
  ],
  mode: 'development'
}

2.2.3 壓縮css

CssMinizerWebpackPlugin插件

2.2.4 js語法檢查

  • 語法檢查: eslint-loader eslint
  • 注意:只檢查自己的代碼阅仔,第三方庫不檢查
    exclude: /node_modules/,
  • 設(shè)置檢查規(guī)則:
    package.json中eslintConfig中設(shè)置
    aribnb --> eslint-config-airbnb-base eslint eslint-plugin-import

package.json中的配置

"eslintConfig": {
  "extends": "airbnb-base"
}

webpack.config.js

module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /node_modules/,
      loader: 'eslint-loader',
      options: {
        // 自動(dòng)修復(fù)
        fix: true,
      },
    },
  ],
},
// 下一行eslint所有規(guī)則都失效
// eslint-disable-next-line

2.2.5 js兼容性處理

  • 基本js兼容性處理
    babel-loader @babel/preset-env
    問題:只能轉(zhuǎn)換基本語法,如promse等不能轉(zhuǎn)換

  • 全部js兼容性處理
    @babel/polyfill(非插件弧械,只需引入)
    問題:只需解決部分兼容性問題八酒,但將所有兼容性代碼引入,體積過大

  • 按需加載兼容性處理
    core-js

module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /node_modules/,
      loader: 'babel-loader',
      options: {
        // 預(yù)設(shè):指示babel做怎么樣的兼容性處理

        // 1. 基本js兼容性處理
        // presets: [
        //   '@babel/preset-env'
        // ]

        // 3. 按需加載兼容性處理
        presets: [
          [
            '@babel/preset-env',
            {
              // 按需加載
              useBuiltIns: 'usage',
              corejs: {
                // 指定corejs版本
                version: 2
              },
              // 指定兼容性做到哪個(gè)版本瀏覽器
              targets: {
                chrome: '60',
                firefox: '50',
                ie: '9',
                safari: '10',
                edge: '17'
              }
            }
          ]
        ]
      }
    }
  ],
},

正常來講刃唐,一個(gè)文件只能被一個(gè)loader處理羞迷,當(dāng)一個(gè)文件要被多個(gè)loader處理時(shí),那么一定要知道loader執(zhí)行的先后順序画饥,先執(zhí)行eslint再執(zhí)行babel
enforce: 'pre'

2.2.6 html壓縮

plugins: [
  new HtmlWebpackPlugin({
    template: './src/index.html',
    minify: {
      // 移除空格
      collapseWhitespace: true,
      // 移除注釋
      removeComments: true
    }
  }),
],

2.2.7 生產(chǎn)環(huán)境基本配置

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { resolve } = require('path');

// 定義node.js環(huán)境變量 決定使用browserlist的哪個(gè)環(huán)境
process.env.NODE_ENV = 'production';

// 服用css配置
const commonCssLoader = [
  // 'style-loader',
  MiniCssExtractPlugin.loader,
  'css-loader',
  // 兼容性處理
  {
    loader: 'postcss-loader',
    // 修改默認(rèn)配置
    options: {
      postcssOptions: {
        plugins: [ require('postcss-preset-env')() ]
      }
    }
    // 還需在package.json中定義browserslist
  //   "browserslist": {
  //   "development": [
  //     "last 1 chrome version",
  //     "last 1 firefox version",
  //     "last 1 safari version"
  //   ],
  //   "production": [
  //     ">0.2%",
  //     "not dead",
  //     "not op_mini all"
  //   ]
  //  },
  },
];

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build'),
  },
  module: {
    rules: [
      // css
      {
        test: /\.css$/,
        use: [...commonCssLoader],
      },
      // less
      {
        test: /\.less$/,
        ues: [...commonCssLoader, 'less-loader'],
      },

      /*
        正常來講衔瓮,一個(gè)文件只能被一個(gè)loader處理
        當(dāng)一個(gè)文件要被多個(gè)loader處理,那么一定要知道loader執(zhí)行的先后順序
          先執(zhí)行eslint再執(zhí)行babel
      */
      // js語法檢查
      {
        test: /\.js$/,
        exclude: /node_modules/,
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true,
        },
        // package.json
        // "eslintConfig": {
        //   "extends": "airbnb-base"
        // }
      },
      // js兼容性處理
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: [
            [
              '@babel/preset-env',
              {
                useBuiltIns: 'usage',
                corejs: {
                  version: 2,
                },
                targets: {
                  chrome: '60',
                  firefox: '59',
                },
              },
            ],
          ],
        },
      },
      // 圖片
      {
        test: /\.(jpg|png|gif)/,
        loader: 'url-loader',
        options: {
          limit: 8 * 1024,
          name: '[hash:10].[ext]',
          outputPath: 'img',
          esModule: false,
        },
      },
      // html圖片
      {
        test: /\.html/,
        loader: 'html-loader',
      },
      // 其他文件
      {
        exclude: /\.(js|css|less|html|jpg|png|gif)/,
        loader: 'file-loader',
        options: {
          outputPath: 'media',
        },
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/built.css',
    }),
    new CssMinimizerWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html',
      minify: {
        collapseWhitespace: true,
        removeComments: true,
      },
    }),
  ],
  // js壓縮
  mode: 'production',
};

三抖甘、webpack性能優(yōu)化

3.1 開發(fā)環(huán)境性能優(yōu)化

  • 優(yōu)化打包構(gòu)建速度
  • 優(yōu)化代碼調(diào)試

HMR 功能

  • 作用:一個(gè)模塊發(fā)生變化热鞍,只會(huì)重新打包這一個(gè)模塊(而不是所有模塊)
  • 注意:
    ① 樣式文件可以使用HMR功能,因?yàn)閟tyle-loader內(nèi)部實(shí)現(xiàn)了
    ② html文件默認(rèn)不能使用HMR功能(不用做HMR功能)
    ③ js文件默認(rèn)不能使用HMR功能,需要修改js代碼(webpack配置target: 'web')
if (module.hot) {
  // 一旦module.hot為true薇宠,說明開啟了HMR功能偷办,需要讓HMR代碼功能生效
  module.hot.accept('./print.js', function () {
    // 方法監(jiān)聽print.js文件的變化,一旦發(fā)生變化澄港,其他默認(rèn)不會(huì)重新打包構(gòu)建
    // 會(huì)執(zhí)行后面的回調(diào)函數(shù)
    print()
  })
}

source-map

一種提供源代碼到構(gòu)建后代碼的映射技術(shù)(如果構(gòu)建后代碼出錯(cuò)了椒涯,通過映射可以追蹤到源代碼作物)

/* webpack.config.js */
devtool: 'source-map'
參數(shù) 內(nèi)/外 作用
source-map 外部生成source-map文件 錯(cuò)誤代碼準(zhǔn)確信息和源代碼的錯(cuò)誤位置
inline-source-map 內(nèi)嵌source-map,構(gòu)建速度快 錯(cuò)誤代碼準(zhǔn)確信息和源代碼的錯(cuò)誤位置
hidden-source-map 外部生成source-map文件 錯(cuò)誤代碼原因回梧,但是沒有錯(cuò)誤位置废岂,不能追蹤源代碼錯(cuò)誤,只能提示到構(gòu)建后代碼位置
eval-source-map 內(nèi)嵌(每一個(gè)文件都生成一個(gè)source-map) 錯(cuò)誤代碼準(zhǔn)確信息和源代碼的錯(cuò)誤位置
nosources-source-map 外部 錯(cuò)誤代碼準(zhǔn)確信息漂辐,但是沒有任何源代碼信息
cheap-source-map 外部 錯(cuò)誤代碼準(zhǔn)確信息和源代碼的錯(cuò)誤位置泪喊,只能精確到行
cheap-module-source-map 外部 錯(cuò)誤代碼準(zhǔn)確信息和源代碼的錯(cuò)誤位置,會(huì)將loader的source map加入
  • 開發(fā)環(huán)境:速度快髓涯、調(diào)試友好

    • 速度快(eval>inline>cheap>...)
      eval-cheap-source-map
      eval-source-map(推薦)
    • 調(diào)試更友好
      source-map
      cheap-module-source-map
      cheap-source-map
  • 生產(chǎn)環(huán)境:源代碼要不要隱藏袒啼?調(diào)試要不要更友好?
    內(nèi)嵌會(huì)讓代碼體積變大纬纪,所以生產(chǎn)環(huán)境不用內(nèi)嵌
    nosources-source-map 全部隱藏
    hidden-source-map 只隱藏源代碼

    source-map/cheap-module-source-map (推薦)

3.2 生產(chǎn)環(huán)境性能優(yōu)化

3.2.1 優(yōu)化打包構(gòu)建速度

oneOf

oneOf:匹配到 loader 后就不再向后進(jìn)行匹配蚓再,優(yōu)化生產(chǎn)環(huán)境的打包構(gòu)建速度

module: {
  rules: [
    {
      // js 語法檢查
      test: /\.js$/,
      exclude: /node_modules/,
      // 優(yōu)先執(zhí)行
      enforce: 'pre',
      loader: 'eslint-loader',
      options: {
        fix: true
      }
    },
    {
      // oneOf 優(yōu)化生產(chǎn)環(huán)境的打包構(gòu)建速度
      // 以下loader只會(huì)匹配一個(gè)(匹配到了后就不會(huì)再往下匹配了)
      // 注意:不能有兩個(gè)配置處理同一種類型文件(所以把eslint-loader提取出去放外面)
      oneOf: [
        {
          test: /\.css$/,
          use: [...commonCssLoader]
        },
        {
          test: /\.less$/,
          use: [...commonCssLoader, 'less-loader']
        },
        {
          // js 兼容性處理
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel-loader',
          options: {
            presets: [
              [
                '@babel/preset-env',
                {
                  useBuiltIns: 'usage',
                  corejs: {version: 3},
                  targets: {
                    chrome: '60',
                    firefox: '50'
                  }
                }
              ]
            ]
          }
        },
        {
          test: /\.(jpg|png|gif)/,
          loader: 'url-loader',
          options: {
            limit: 8 * 1024,
            name: '[hash:10].[ext]',
            outputPath: 'imgs',
            esModule: false
          }
        },
        {
          test: /\.html$/,
          loader: 'html-loader'
        },
        {
          exclude: /\.(js|css|less|html|jpg|png|gif)/,
          loader: 'file-loader',
          options: {
            outputPath: 'media'
          }
        }
      ]
    }
  ]
},

緩存

  • babel緩存
    配置cacheDirectory: true
    讓第二次打包構(gòu)建速度更快
  • 文件資源緩存
    • hash:每次webpack打包時(shí)會(huì)生成一個(gè)唯一的hash值
      問題:因?yàn)閖s和css同時(shí)使用一個(gè)hash值如果重新打包會(huì)導(dǎo)致所有緩存失效。
    • chunkhash:根據(jù)chunk生成的hash值包各,如果打包來源于同一個(gè)chunk摘仅,那么hash值就一樣
      問題:js和css的hash值還是一樣,因?yàn)閏ss是在js中被引入的问畅,同屬一個(gè)chunk
    • contenthash:根據(jù)文件的內(nèi)容生成hash值
      讓代碼上線運(yùn)行緩存更好使用

多進(jìn)程打包

優(yōu)化打包速度
問題: 進(jìn)程啟動(dòng)大概為600ms,進(jìn)程通信也有開銷.
只有打包工作消耗時(shí)間比較長,才需要多進(jìn)程打包

// 再某個(gè)loader后(數(shù)組前)使用thread-loader可對(duì)相應(yīng)loader進(jìn)行多進(jìn)程打包
/* 
  多進(jìn)程打包
*/
{
  loader: "thread-loader",
  options: {
    workers: 2 // 進(jìn)程數(shù)
  }
},

externals

防止將某些方法打包到最終輸出的bundle中

// webpack.config.js中配置
externals: {
  // 忽略庫名 npm包名
  // 拒絕jquery被打包
  jquery: 'jQuery'
}
再將需要的包在html中引入

dll

動(dòng)態(tài)鏈接庫
類似externals,指示哪些庫不需要打包,不同在于dll會(huì)將某些庫進(jìn)行單獨(dú)打包成chunk.

  • webpack.dll.js 配置:(將 jquery 單獨(dú)打包)
/*
  node_modules的庫會(huì)打包到一起娃属,但是很多庫的時(shí)候打包輸出的js文件就太大了
  使用dll技術(shù),對(duì)某些庫(第三方庫:jquery护姆、react矾端、vue...)進(jìn)行單獨(dú)打包
  當(dāng)運(yùn)行webpack時(shí),默認(rèn)查找webpack.config.js配置文件
  需求:需要運(yùn)行webpack.dll.js文件
    --> webpack --config webpack.dll.js(運(yùn)行這個(gè)指令表示以這個(gè)配置文件打包)
*/
const { resolve } = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    // 最終打包生成的[name] --> jquery
    // ['jquery] --> 要打包的庫是jquery
    jquery: ['jquery']
  },
  output: {
    // 輸出出口指定
    filename: '[name].js', // name就是jquery
    path: resolve(__dirname, 'dll'), // 打包到dll目錄下
    library: '[name]_[hash]', // 打包的庫里面向外暴露出去的內(nèi)容叫什么名字
  },
  plugins: [
    // 打包生成一個(gè)manifest.json --> 提供jquery的映射關(guān)系(告訴webpack:jquery之后不需要再打包和暴露內(nèi)容的名稱)
    new webpack.DllPlugin({
      name: '[name]_[hash]', // 映射庫的暴露的內(nèi)容名稱
      path: resolve(__dirname, 'dll/manifest.json') // 輸出文件路徑
    })
  ],
  mode: 'production'
};
  • webpack.config.js 配置:(告訴 webpack 不需要再打包 jquery卵皂,并將之前打包好的 jquery 跟其他打包好的資源一同輸出到 build 目錄下)
// 引入插件
const webpack = require('webpack');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');

// plugins中配置:
plugins: [
  new HtmlWebpackPlugin({
    template: './src/index.html'
  }),
  // 告訴webpack哪些庫不參與打包秩铆,同時(shí)使用時(shí)的名稱也得變
  new webpack.DllReferencePlugin({
    manifest: resolve(__dirname, 'dll/manifest.json')
  }),
  // 將某個(gè)文件打包輸出到build目錄下,并在html中自動(dòng)引入該資源
  new AddAssetHtmlWebpackPlugin({
    filepath: resolve(__dirname, 'dll/jquery.js')
  })
],

3.2.2 優(yōu)化代碼運(yùn)行性能

tree shaking

去除無用代碼灯变,減少打包體積

  • 前提

    1. 必須使用ES6模塊化
    2. production環(huán)境
  • 在package.json中配置
    "sideEffects": false 所有代碼都沒有副作用(都可以進(jìn)行tree shaking)
    問題:可能會(huì)把css/@babel/polyfill 文件干掉
    解決:"sideEffects": ["*.css"]

代碼分割 code split

打包成一個(gè)代碼體積大殴玛,需要分隔開

方法
  1. 多入口
    多個(gè)entry
  2. splitChunks
    可以將node_modules中的代碼單獨(dú)打包成一個(gè)chunk最終輸出(比如多入口文件中有重復(fù)的依賴,使用該方法單獨(dú)加載依賴避免重復(fù)加載)
optimization: {
  splitChunks: {
    chunks: 'all'
  }
},
  1. 通過js代碼讓某個(gè)文件單獨(dú)打包成一個(gè)chunk(常用)
    import動(dòng)態(tài)導(dǎo)入語法添祸,能將某個(gè)文件單獨(dú)打包
import(/* webpackChunkName: 'test' */'./test')
  .then(({ mul, count }) => {
    console.log(mul(2, 5));
  })
  .catch(() => {
    console.log('err');
  })

懶加載

// 懶加載
import(/* webpackChunkName: 'test', webpackPrefetch: true */'.test')
  .then(({ mul })=> {
    console.log(mul(4, 6));
  })

正常加載:可以認(rèn)為是并行加載(同時(shí)加載多個(gè)文件)
懶加載:文件需要用時(shí)加載
預(yù)加載webpackPrefetch:會(huì)在使用之前提前加載js文件滚粟,等其他資源加載完畢空閑時(shí)加載該資源

PWA

漸進(jìn)式網(wǎng)絡(luò)開發(fā)應(yīng)用程序(離線可訪問)
workbox --> workbox-webpack-plugin

// webpack.config.js插件
// PWA
new WorkboxWebpackPlugin.GenerateSW({
  // 1. 幫助serviceworker快速啟動(dòng)
  // 2. 刪除舊的serviceworker
  // 生成一個(gè)serviceworker配置文件
  clientsClaim: true,
  skipWaiting: true
})
// js文件配置
/* 
  問題1: eslint不認(rèn)識(shí)window,navigator全局變量
  解決: 需要修改package.json中eslintConfig的配置
  "env": {
    "browser": true // 支持瀏覽器端全局變量
  }

  問題2: sw代碼必須運(yùn)行在服務(wù)器上
*/
// 注冊(cè)serviceworker
// 處理兼容性問題
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js').then(() => {
      console.log('success');
    }).catch(() => {
      console.log('err');
    })
  })
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市刃泌,隨后出現(xiàn)的幾起案子坦刀,更是在濱河造成了極大的恐慌愧沟,老刑警劉巖蔬咬,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲤遥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡林艘,警方通過查閱死者的電腦和手機(jī)盖奈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狐援,“玉大人钢坦,你說我怎么就攤上這事∩督矗” “怎么了爹凹?”我有些...
    開封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長镶殷。 經(jīng)常有香客問我禾酱,道長,這世上最難降的妖魔是什么绘趋? 我笑而不...
    開封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任颤陶,我火速辦了婚禮,結(jié)果婚禮上陷遮,老公的妹妹穿的比我還像新娘滓走。我一直安慰自己,他們只是感情好帽馋,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開白布搅方。 她就那樣靜靜地躺著,像睡著了一般绽族。 火紅的嫁衣襯著肌膚如雪姨涡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天项秉,我揣著相機(jī)與錄音绣溜,去河邊找鬼。 笑死娄蔼,一個(gè)胖子當(dāng)著我的面吹牛怖喻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播岁诉,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼锚沸,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了涕癣?” 一聲冷哼從身側(cè)響起哗蜈,我...
    開封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后距潘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炼列,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年音比,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了俭尖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洞翩,死狀恐怖稽犁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情骚亿,我是刑警寧澤已亥,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站来屠,受9級(jí)特大地震影響虑椎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜的妖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一绣檬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嫂粟,春花似錦娇未、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宽涌,卻和暖如春平夜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卸亮。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來泰國打工忽妒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人兼贸。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓段直,卻偏偏與公主長得像,于是被迫代替她去往敵國和親溶诞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鸯檬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 命令窗口運(yùn)行初始化eslint切換到./node_modules/.bin/文件夾下運(yùn)行 eslint --ini...
    BigTooth_3611閱讀 317評(píng)論 0 0
  • 安裝開發(fā)服務(wù)器webpack-dev-server避免開發(fā)過程中重復(fù)的打包操作,自動(dòng)編譯打包螺垢、自動(dòng)刷新瀏覽器喧务,開發(fā)...
    coder勇閱讀 258評(píng)論 0 0
  • Webpack 是一個(gè)前端資源加載/打包工具赖歌。它將根據(jù)模塊的依賴關(guān)系進(jìn)行靜態(tài)分析,然后將這些模塊按照指定的規(guī)則生成...
    EarthChen閱讀 397評(píng)論 0 1
  • webpack學(xué)習(xí)筆記 注意本筆記只能作為參考功茴,如有錯(cuò)誤希望大家指正一下庐冯。 基礎(chǔ)屬性例子 入口(entry) 描述...
    Demonskp閱讀 237評(píng)論 0 0
  • 1、HTML痊土、CSS和JS代碼壓縮 JS文件的壓縮webpack4內(nèi)置了uglifyjs-webpack-plug...
    wayne1125閱讀 244評(píng)論 0 1