一、了解webpack
高級配置:
1、什么是webpack
高級配置:
進行
Webpack
優化,讓代碼在編譯或者運行時性能更好
2、webpack
優化從哪些方面入手:
① 提升開發體驗,增強開發和生產環境的代碼調試:
如果代碼編寫出錯了,在瀏覽器查看錯誤并且需要定位的時候,查看的是編譯后的代碼,難以定位具體的錯誤位置
② 提升打包構建速度:
(1) 模塊更新:
開發時我們修改了其中一個模塊代碼,
Webpack
默認會將所有模塊全部重新打包編譯,速度很慢。
(2) 打包優化:
打包時每個文件都會匹配所有
loader
,速度比較慢。
(3) 第三方插件編譯:
使用第三方的庫或插件時,所有資源都會下載到
node_modules
中,這些資源是不需要編譯可以直接使用的。
(4) eslint
和babel
緩存:
每次打包時
js
文件都要經過Eslint
檢査 和Babel
編譯,速度比較慢。
(5) 多進程js
文件打包:
當項目越來越龐大時,打包速度就會越來越慢。對
js
文件處理主要就是eslint
、babel
、Terser
三個工具,所以我們要提升它們的運行速度,。我們可以開啟多進程同時處理js
文件,這樣速度就比之前的單進程打包更快了。
③ 減少代碼體積:
(1)第三方工具庫引用:
對于自定義的工具函數庫,或者引用第三方工具函數庫、組件庫。實際上可能只用上極小部分的功能,如果沒有特殊處理,打包時會引入整個庫,體積太大
(2)Babel
編譯時代碼重復插入:
Babel
為編譯的每個文件都插入了輔助代碼,使代碼體積過大
(3)壓縮本地靜態資源中的圖片:
如果項目中引用了較多圖片,那么圖片體積會比較大,請求的速度就會比較慢
④ 優化代碼運行性能:
(1)代碼分割:
打包代碼時會將所有
js
文件打包到一個文件中。如果只要渲染首頁,就應該只加載首頁的js
文件,其他文件不應該加載。
(2)
(3)
(4)
二、提升開發體驗:SourceMap
中文文檔:https://webpack.docschina.org/configuration/devtool/#root
1、SourceMap
的定義:
SourceMap
(源代碼映射)是一個用來生成源代碼與構建后代碼一一映射的文件的方案。
2、為什么能優化調試:
① 使用SourceMap
后,會生成一個 xxx.map
文件,里面包含源代碼和構建后的代碼每一行、每一列的映射關系。
② 瀏覽器會自動查找xxx.map
文件
③ 當代碼出錯時,瀏覽器會提示源代碼文件出錯位置(通過 xxx.map
文件,從構建后代碼出錯位置找到映射后源代碼出錯位置)
3、SourceMap
的使用:
① 開發模式:devtool: 'cheap-module-source-map'
- 優點:打包編譯速度快,只包含行映射
- 缺點:沒有列映射
mode: 'development',
devtool: 'cheap-module-source-map'
② 生產模式:devtool: 'source-map'
- 優點:包含行&列映射
- 缺點:打包編譯速度更慢
mode: 'production',
devtool: 'cheap-module-source-map'
三、提升打包構建速度:
1、模塊熱替換:HMR
中文文檔:https://webpack.docschina.org/guides/hot-module-replacement
① 定義:
在程序運行中,替換、添加或刪除模塊,而無需重新加載整個頁面(修改某個模塊代碼,就只有這個模塊代碼需要重新打包編譯,其他模塊不變)
② 使用:webpack5
中是默認開啟的
// 開發服務器:不會輸出資源,在內存中編譯打包
devServer: {host: 'localhost', // 啟動服務器的域名port: '3001', // 啟動服務器的端口號open: true, // 是否自動打開瀏覽器hot: true, // 開啟 HMR(默認值)
}
(1)CSS
模塊熱更新:
css
樣式經過 style-loader
處理,已經具備 HMR
功能了
(2)JS
模塊熱更新:
a、常規寫法:
語法:
// 1. 監聽特定模塊
module.hot.accept('字符串或數組(模塊路徑)', [,'模塊更新后的回調函數'])
// 2. 監聽當前模塊自身
module.hot.accept()
項目中使用:
// 配置js模塊熱更新
if(module.hot) {// 如果支持模塊熱更新module.hot.accept('./js/sum.js')module.hot.accept('./js/util.js')
}
b、vue
或者React
項目寫法:
vue-loader
:https://vue-loader.vuejs.org/
React Fast Refresh
:https://reactnative.dev/docs/fast-refresh
2、模塊熱替換:oneOf
中文文檔:https://webpack.docschina.org/configuration/module/#ruleoneof
① 定義:
只要匹配到一個
loader
,剩下的就不匹配了
② 使用:
// 加載器module: {rules: [{ // 當規則匹配時,只使用第一個匹配規則oneOf: [{test: /\.css$/i, // 匹配以.css結尾的文件use: ['style-loader', // 將js中的css通過style標簽的形式添加到html中'css-loader' // 將css資源編譯成commonjs的模塊化js], // loader的執行順序是從后往前的},{test: /\.less$/i,use: ['style-loader','css-loader','less-loader', // 將less文件編譯為css文件],},{test: /\.s[ac]ss$/i,use: [// 將 JS 字符串生成為 style 節點'style-loader',// 將 CSS 轉化成 CommonJS 模塊'css-loader',// 將 Sass 編譯成 CSS'sass-loader',],},{test: /\.styl$/i,use: ['style-loader','css-loader','stylus-loader', // 將stylus文件編譯為css文件],},{ // webpack4處理圖片資源的方式:使用file-loader、url-loader。// file-loader將文件資源編譯為webpack識別的資源原封不動的進行輸出。// url-loader將圖片資源進行優化// webpack5處理圖片資源的方式(file-loader、url-loader已經內置):test: /\.(png|jpe?g|svg|webp|gif)$/,type: 'asset',parser: {dataUrlCondition: {maxSize: 30 * 1024 // 小于30kb的圖片會轉為base64 - 減少請求數量,但是體積會變大}},generator: { // 打包的圖片輸出的目錄// [hash:10]表示只保留名稱的前10位filename: 'static/images/[hash:10][ext][query]'}},{ // webpack4處理圖片資源的方式:使用file-loader// file-loader將文件資源編譯為webpack識別的資源原封不動的進行輸出。// webpack5處理圖片資源的方式(file-loader已經內置):test: /\.(ttf|woff2?)$/,type: 'asset/resource', // 只會對文件原封不動的輸出,不會轉為base64generator: { // 打包的字體輸出的目錄// [hash:10]表示只保留名稱的前10位filename: 'static/fonts/[hash:10][ext][query]'}},{ // webpack4處理其它資源的方式:使用file-loader// file-loader將文件資源編譯為webpack識別的資源原封不動的進行輸出。// webpack5處理其它資源的方式(file-loader已經內置):test: /\.(mp3|MP4|avi|.doc)$/i,type: 'asset/resource', // 只會對文件原封不動的輸出,不會轉為base64generator: { // 打包的字體輸出的目錄// [name]表示保留原始文件名filename: 'static/media/[hash:10][ext][query]'}},{test: /\.js$/,exclude: /(node_modules)/, // 排除哪些文件不需要編譯loader: 'babel-loader', // 只需要一個loader,不需要use// use: {// loader: 'babel-loader',// options: { // 智能預設,這個對象可以不寫,那么就需要在項目的根目錄下新建babel.config.js,添加智能預設// presets: ['@babel/preset-env'],// },// },}]}]},
3、第三方插件編譯優化:exclude
或者include
中文文檔:https://webpack.docschina.org/configuration/module#ruleexclude
① exclude
定義:
要排除符合條件的資源(對
js
文件處理時,排除node modules
下面的文件)
② include
定義:
只對當前包含的資源進行處理
③ 使用:
//加載器module: {rules: [{ // 當規則匹配時,只使用第一個匹配規則oneOf: [{test: /\.js$/,// exclude: /(node_modules)/, // 排除哪些文件不需要編譯include: path.resolve(__dirname, '../src'), // 哪些文件需要編譯loader: 'babel-loader', // 只需要一個loader,不需要use}]}]},// 插件plugins: [new ESLintPlugin({ // eslint檢測的文件都有哪些exclude: "node_modules", // 默認值,排除哪些文件不需要編譯context: path.resolve(__dirname, '../src')}),new HtmlWebpackPlugin({ // 使用 html資源引入 插件,并且保留原模版template: path.resolve(__dirname, '../index.html')})]
4、 eslint
和babel
緩存:Cache
中文文檔:https://webpack.docschina.org/configuration/cache/#root
① 定義:
緩存之前的
Eslint
檢查 和Babel
編譯結果,加快后續打包速度
② 使用:
打包完成后的緩存js
文件,默認路徑在node_modules/.cache/babel-loader中
module.exports = {// 加載器module: {rules: [{oneOf: [{test: /\.js$/,// exclude: /(node_modules)/, // 排除哪些文件不需要編譯include: path.resolve(__dirname, '../src'), // 哪些文件需要編譯loader: 'babel-loader', // 只需要一個loader,不需要useoptions: {cacheDirectory: true, // 開啟babel緩存cacheCompression: false, // 不壓縮緩存文件}},]}]},// 插件plugins: [new ESLintPlugin({ // eslint檢測的文件都有哪些exclude: "node_modules", // 默認值,排除哪些文件不需要編譯context: path.resolve(__dirname, '../src'),cache: true, // 開啟緩存cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache'), // 緩存文件存儲的路徑}),new HtmlWebpackPlugin({ // 使用 html資源引入 插件,并且保留原模版template: path.resolve(__dirname, '../index.html')}),new MiniCssExtractPlugin({ // 將所有的css提取到一個單獨的文件中filename: 'static/css/main.css'}),new CssMinimizerPlugin()],
}
5、 多進程打包:Thead
中文文檔:https://webpack.docschina.org/loaders/thread-loader/#root
① 定義:
開啟電腦的多個進程同時干一件事,速度更快。
需要注意:請僅在特別耗時的操作中使用,因為每個進程啟動就有大約為600ms
左右開銷
② 使用:
(1)獲取 cpu
的核數:
啟動的進程最大數量就是cpu
的核數
// 引入os模塊
const os = require('os')
// 獲取cpu的核數
const threads = os.cpus().length;
(2)下載包:
npm install --save-dev thread-loader
(3)使用:
a、js
編譯多核處理:
{test: /\.js$/,// exclude: /(node_modules)/, // 排除哪些文件不需要編譯include: path.resolve(__dirname, '../src'), // 哪些文件需要編譯use: [{loader: 'thread-loader', // 開啟多進程options: {// 產生的 worker 的數量,默認是 (cpu 核心數 - 1)workers: threads,}},{loader: 'babel-loader', // 只需要一個loader,不需要useoptions: {cacheDirectory: true, // 開啟babel緩存cacheCompression: false, // 不壓縮緩存文件}}]
}
b、eslint
多核處理:
plugins: [new ESLintPlugin({ // eslint檢測的文件都有哪些exclude: "node_modules", // 默認值,排除哪些文件不需要編譯context: path.resolve(__dirname, '../src'),cache: true, // 開啟緩存cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache'), // 緩存文件存儲的路徑threads // 開啟多進程})
],
c、壓縮js
多核處理:
// 引入 js壓縮 插件 -- 內置
const terserWebpackPlugin = require('terser-webpack-plugin')
module.exports = {plugins: [// new CssMinimizerPlugin(),// new terserWebpackPlugin({// parallel: threads, // 開啟多進程// })],optimization: { // 不在這里寫的話,可以在 plugins 中寫minimizer: [new CssMinimizerPlugin(),new terserWebpackPlugin({parallel: threads, // 開啟多進程})],},
}
③ 完整代碼:
webpack.prod.js
:
// 引入os模塊
const os = require('os')
// 引入path模塊
const path = require('path')
// 引入 eslint 插件
const ESLintPlugin = require('eslint-webpack-plugin');
// 引入 html資源引入 插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 引入 提取css 的插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 引入 css壓縮 插件
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
// 引入 js壓縮 插件 -- 內置
const terserWebpackPlugin = require('terser-webpack-plugin')// 獲取cpu的核數
const threads = os.cpus().length;// 封裝樣式打包代碼
function getStyleLoader (otherPre) {return [MiniCssExtractPlugin.loader, // 將 css 文件打包為一個單獨的文件'css-loader', // 將css資源編譯成commonjs的模塊化js{ // 需要配置就寫成對象的形式,不需要配置就寫成字符串的形式loader: 'postcss-loader',options: { // css 的兼容性處理配置postcssOptions: {plugins: [['postcss-preset-env',{// 其他選項},],],},},},otherPre].filter(Boolean)
}module.exports = {// 入口 - 相對路徑(因為編譯的時候,命令是從根目錄下執行的,所以不用修改)entry: './src/main.js',// 輸出output: {// 所有打包的資源輸出的目錄 - 絕對路徑(打包的時候,是根據該文件進行定位的)path: path.resolve(__dirname,'../dist'), // 入口文件打包輸出的名稱filename: 'static/js/main.js',// 在打包前,會清空path目錄中的所有內容,然后再進行打包 -- webpack5中使用// 如果是webpack4,則需要使用clean-webpack-plugin插件進行清空clean: true // 開發時不需要},// 加載器module: {rules: [{oneOf: [{test: /\.css$/i, // 匹配以.css結尾的文件use: getStyleLoader(), // loader的執行順序是從后往前的},{test: /\.less$/i,use: getStyleLoader('less-loader')},{test: /\.s[ac]ss$/i,use: getStyleLoader('sass-loader')},{test: /\.styl$/i,use: getStyleLoader('stylus-loader')},{ // webpack4處理圖片資源的方式:使用file-loader、url-loader。// file-loader將文件資源編譯為webpack識別的資源原封不動的進行輸出。// url-loader將圖片資源進行優化// webpack5處理圖片資源的方式(file-loader、url-loader已經內置):test: /\.(png|jpe?g|svg|webp|gif)$/,type: 'asset',parser: {dataUrlCondition: {maxSize: 30 * 1024 // 小于30kb的圖片會轉為base64 - 減少請求數量,但是體積會變大}},generator: { // 打包的圖片輸出的目錄// [hash:10]表示只保留名稱的前10位filename: 'static/images/[hash:10][ext][query]'}},{ // webpack4處理圖片資源的方式:使用file-loader// file-loader將文件資源編譯為webpack識別的資源原封不動的進行輸出。// webpack5處理圖片資源的方式(file-loader已經內置):test: /\.(ttf|woff2?)$/,type: 'asset/resource', // 只會對文件原封不動的輸出,不會轉為base64generator: { // 打包的字體輸出的目錄// [hash:10]表示只保留名稱的前10位filename: 'static/fonts/[hash:10][ext][query]'}},{ // webpack4處理其它資源的方式:使用file-loader// file-loader將文件資源編譯為webpack識別的資源原封不動的進行輸出。// webpack5處理其它資源的方式(file-loader已經內置):test: /\.(mp3|MP4|avi|.doc)$/i,type: 'asset/resource', // 只會對文件原封不動的輸出,不會轉為base64generator: { // 打包的字體輸出的目錄// [name]表示保留原始文件名filename: 'static/media/[hash:10][ext][query]'}},{test: /\.js$/,// exclude: /(node_modules)/, // 排除哪些文件不需要編譯include: path.resolve(__dirname, '../src'), // 哪些文件需要編譯// loader: 'babel-loader', // 只需要一個loader,不需要use// options: {// cacheDirectory: true, // 開啟babel緩存// cacheCompression: false, // 不壓縮緩存文件// }// use: {// loader: 'babel-loader',// options: { // 智能預設,這個對象可以不寫,那么就需要在項目的根目錄下新建babel.config.js,添加智能預設// presets: ['@babel/preset-env'],// },// },use: [{loader: 'thread-loader', // 開啟多進程options: {// 產生的 worker 的數量,默認是 (cpu 核心數 - 1)workers: threads,}},{loader: 'babel-loader', // 只需要一個loader,不需要useoptions: {cacheDirectory: true, // 開啟babel緩存cacheCompression: false, // 不壓縮緩存文件}}]},]}]},optimization: { // 不在這里寫的話,可以在 plugins 中寫minimizer: [new CssMinimizerPlugin(),new terserWebpackPlugin({parallel: threads, // 開啟多進程})],},// 插件plugins: [new ESLintPlugin({ // eslint檢測的文件都有哪些exclude: "node_modules", // 默認值,排除哪些文件不需要編譯context: path.resolve(__dirname, '../src'),cache: true, // 開啟緩存cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache'), // 緩存文件存儲的路徑threads // 開啟多進程}),new HtmlWebpackPlugin({ // 使用 html資源引入 插件,并且保留原模版template: path.resolve(__dirname, '../index.html')}),new MiniCssExtractPlugin({ // 將所有的css提取到一個單獨的文件中filename: 'static/css/main.css'}),// new CssMinimizerPlugin(),// new terserWebpackPlugin({// parallel: threads, // 開啟多進程// })],// 模式mode: 'production',devtool: 'source-map'
}
webpack.dev.js
:
// 引入os模塊
const os = require('os')
// 引入path模塊
const path = require('path')
// 引入 eslint 插件
const ESLintPlugin = require('eslint-webpack-plugin');
// 引入 html資源引入 插件
const HtmlWebpackPlugin = require('html-webpack-plugin');// 獲取cpu的核數
const threads = os.cpus().length;module.exports = {// 入口 - 相對路徑(因為編譯的時候,命令是從根目錄下執行的,所以不用修改)entry: './src/main.js',// 輸出output: {// 所有打包的資源輸出的目錄 - 絕對路徑(打包的時候,是根據該文件進行定位的)// path: path.resolve(__dirname, '../dist'), path: undefined, // 開發模式不會輸出文件// 入口文件打包輸出的名稱filename: 'static/js/main.js',// 在打包前,會清空path目錄中的所有內容,然后再進行打包 -- webpack5中使用// 如果是webpack4,則需要使用clean-webpack-plugin插件進行清空// clean: true // 開發時不需要},// 加載器module: {rules: [{ // 當規則匹配時,只使用第一個匹配規則oneOf: [{test: /\.css$/i, // 匹配以.css結尾的文件use: ['style-loader', // 將js中的css通過style標簽的形式添加到html中'css-loader' // 將css資源編譯成commonjs的模塊化js], // loader的執行順序是從后往前的},{test: /\.less$/i,use: ['style-loader','css-loader','less-loader', // 將less文件編譯為css文件],},{test: /\.s[ac]ss$/i,use: [// 將 JS 字符串生成為 style 節點'style-loader',// 將 CSS 轉化成 CommonJS 模塊'css-loader',// 將 Sass 編譯成 CSS'sass-loader',],},{test: /\.styl$/i,use: ['style-loader','css-loader','stylus-loader', // 將stylus文件編譯為css文件],},{ // webpack4處理圖片資源的方式:使用file-loader、url-loader。// file-loader將文件資源編譯為webpack識別的資源原封不動的進行輸出。// url-loader將圖片資源進行優化// webpack5處理圖片資源的方式(file-loader、url-loader已經內置):test: /\.(png|jpe?g|svg|webp|gif)$/,type: 'asset',parser: {dataUrlCondition: {maxSize: 30 * 1024 // 小于30kb的圖片會轉為base64 - 減少請求數量,但是體積會變大}},generator: { // 打包的圖片輸出的目錄// [hash:10]表示只保留名稱的前10位filename: 'static/images/[hash:10][ext][query]'}},{ // webpack4處理圖片資源的方式:使用file-loader// file-loader將文件資源編譯為webpack識別的資源原封不動的進行輸出。// webpack5處理圖片資源的方式(file-loader已經內置):test: /\.(ttf|woff2?)$/,type: 'asset/resource', // 只會對文件原封不動的輸出,不會轉為base64generator: { // 打包的字體輸出的目錄// [hash:10]表示只保留名稱的前10位filename: 'static/fonts/[hash:10][ext][query]'}},{ // webpack4處理其它資源的方式:使用file-loader// file-loader將文件資源編譯為webpack識別的資源原封不動的進行輸出。// webpack5處理其它資源的方式(file-loader已經內置):test: /\.(mp3|MP4|avi|.doc)$/i,type: 'asset/resource', // 只會對文件原封不動的輸出,不會轉為base64generator: { // 打包的字體輸出的目錄// [name]表示保留原始文件名filename: 'static/media/[hash:10][ext][query]'}},{test: /\.js$/,// exclude: /(node_modules)/, // 排除哪些文件不需要編譯include: path.resolve(__dirname, '../src'), // 哪些文件需要編譯// loader: 'babel-loader', // 只需要一個loader,不需要use// // use: {// // loader: 'babel-loader',// // options: { // 智能預設,這個對象可以不寫,那么就需要在項目的根目錄下新建babel.config.js,添加智能預設// // presets: ['@babel/preset-env'],// // },// // },use: [{loader: 'thread-loader', // 開啟多進程options: {// 產生的 worker 的數量,默認是 (cpu 核心數 - 1)workers: threads,}},{loader: 'babel-loader', // 只需要一個loader,不需要useoptions: {cacheDirectory: true, // 開啟babel緩存cacheCompression: false, // 不壓縮緩存文件}}]}]}]},// 插件plugins: [new ESLintPlugin({ // eslint檢測的文件都有哪些exclude: "node_modules", // 默認值,排除哪些文件不需要編譯context: path.resolve(__dirname, '../src'),cache: true, // 開啟緩存cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache'), // 緩存文件存儲的路徑threads // 開啟多進程}),new HtmlWebpackPlugin({ // 使用 html資源引入 插件,并且保留原模版template: path.resolve(__dirname, '../index.html')})],// 開發服務器:不會輸出資源,在內存中編譯打包devServer: {host: 'localhost', // 啟動服務器的域名port: '3001', // 啟動服務器的端口號open: true, // 是否自動打開瀏覽器hot: true, // 開啟 HMR(默認值)},// 模式mode: 'development',devtool: 'cheap-module-source-map'
}
四、減少代碼體積:
1、第三方工具庫引用:Tree shaking
① 定義:
用于移除
JavaScript
中的沒有使用的代碼。
注意:它依賴 ES Module
② 使用:
Webpack
已經默認開啟了這個功能,無需其他配置,
2、Babel
編譯時代碼重復插入:@babel/plugin-transform-runtime
中文文檔:https://webpack.docschina.org/loaders/babel-loader/#babel-is-injecting-helpers-into-each-file-and-bloating-my-code
① 定義:
禁用了
Babel
自動對每個文件的runtime
注入。將輔助代碼作為一個獨立模塊,保存在@babel/plugin-transform-runtime
中,需要的時候從@babel/plugin-transform-runtime
進行引入。
② 下載包:
npm install -D @babel/plugin-transform-runtime
③ 使用:
module.exports = {// 加載器module: {rules: [{oneOf: [{test: /\.js$/,// exclude: /(node_modules)/, // 排除哪些文件不需要編譯include: path.resolve(__dirname, '../src'), // 哪些文件需要編譯use: [{loader: 'thread-loader', // 開啟多進程options: {// 產生的 worker 的數量,默認是 (cpu 核心數 - 1)workers: threads,}},{loader: 'babel-loader', // 只需要一個loader,不需要useoptions: {cacheDirectory: true, // 開啟babel緩存cacheCompression: false, // 不壓縮緩存文件plugins: ['@babel/plugin-transform-runtime'], // 減少代碼體積}}]},]}]}
}
3、壓縮本地靜態資源中的圖片:
中文文檔:https://webpack.docschina.org/plugins/image-minimizer-webpack-plugin/#root
① 下載包:
npm install image-minimizer-webpack-plugin imagemin --save-dev
② 下載有損壓縮包:體積更小,但是圖片質量會受影響
npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev
③ 下載無損壓縮包:體積更大,但是圖片質量比較好
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev
(1)安裝失敗:可以使用cnpm
進行安裝
cnpm
安裝使用鏈接:https://blog.csdn.net/Y1914960928/article/details/134706252
(2)uuid
安裝包版本太低:
在 package.json
中強制更新:
"overrides": {"uuid": "^9.0.0"},
④ 配置無損壓縮:
// 引入 圖片壓縮 插件
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');module.exports = {// 插件plugins: [new ImageMinimizerPlugin({ // 配置圖片無損壓縮minimizer: {implementation: ImageMinimizerPlugin.imageminGenerate,options: {plugins: [['gifsicle', { interlaced: true }],['jpegtran', { progressive: true }],['optipng', { optimizationLevel: 5 }],['svgo', {plugins: ["preset-default","prefixIds",{name: "sortAttrs",params: {xmlnsOrder: "alphabetical",},},]},],],}},}),]
}
五、優化代碼運行性能:
1、代碼分割:CodeSplit
① 功能:
(1)分割文件:
將打包生成的文件進行分割,生成多個
js
文件
(2)按需加載:
需要哪個文件就加載哪個文件
② 方法一:將js
文件打包拆分為多入口
(1)多入口文件中復用的代碼需要打包到單獨的文件中(提取公共模塊):
中文文檔:https://webpack.docschina.org/plugins/split-chunks-plugin#root
webpack.config.js
文件中寫入代碼:
const path = require('path')const htmlWebpackPlugin = require('html-webpack-plugin')module.exports = {// entry: './src/main.js',entry: { // 多入口app: './src/app.js',main: './src/main.js'},output: {path: path.resolve(__dirname, 'dist'),filename: '[name].js'},plugins: [new htmlWebpackPlugin({template: path.resolve(__dirname, 'public/index.html'),})],optimization: { // 代碼分割 配置splitChunks: {chunks: 'all', // 對所有模塊都進行分割// 以下是默認值// minSize: 20000, // 分割的代碼最小體積// minRemainingSize: 0, // 分割代碼后的最小體積,確保提取的文件大小不能為0// minChunks: 1, // 最少被引用的次數,滿足條件才會代碼分割// maxAsyncRequests: 30, // 按需加載時,并行加載的文件的最大數量// maxInitialRequests: 30, // 入口js文件中,最大的并行請求數量// enforceSizeThreshold: 50000, // 超過 50kb 一定會被單獨打包(此時會忽略minRemainingSize、maxAsyncRequests、maxInitialRequests)// cacheGroups: { // 緩存組,將所有模塊分為不同的緩存組(哪些模塊會被打包到一個組)// defaultVendors: { // 組名// test: /[\\/]node_modules[\\/]/, // 將 node_modules 中的代碼打包到 vendors 組// priority: -10, // 優先級,數值越大,越先被打包// reuseExistingChunk: true, // 如果當前模塊已經被打包,就直接復用,而不是重新打包// },// default: { // 可以在這里進行默認值的更改// minChunks: 2,// priority: -20,// reuseExistingChunk: true,// },// },cacheGroups: {default: {minSize: 0,minChunks: 2,priority: -20,reuseExistingChunk: true,},}},},mode: 'development'
}
(2)按需加載,動態引入:
main.js
中的代碼如下:
// 使用公共文件中的方法 sum
import {sum} from "./math"
console.log(sum(4,5))
console.log('這是main.js')
// 靜態加載
// import calc from './calc.js'document.getElementById('btn').addEventListener('click', () => {// console.log('點擊按鈕', calc(2,3))// import 的動態引入import('./calc.js').then((module) => {console.log('模塊動態加載成功',module.default(4,5))}).catch((err) => {console.log('模塊動態加載失敗',err)})
})
③ 方法二:單入口文件進行按需加載
webpack.config.js
文件中寫入代碼:
module.exports = {optimization: { // 代碼分割 配置splitChunks: {chunks: 'all', // 對所有模塊都進行分割}
}
請注意:如果eslint
不支持動態的導入語法,需要新增插件:import