Webpack基礎配置:
語法解析:babel-loader
樣式解析:style-loader
css解析:css-loader
less解析:less-loader
檔案解析:url-loader(file-loalder)
效能分析:webpack-bundle-analyzer
程式碼:
var path = require('path'); var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { mode: "development", entry: './app.js', output: { path: path.resolve(__dirname, './build/'), filename: "source.js", }, devtool: "source-map", module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', } }, { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }, { test: /\.(png|jpg|gif|svg|jpeg)$/, use: [ { loader: 'url-loader', options: { limit: 1000 * 100 } } ] }, { test: /\.less$/, use: [ "style-loader", // creates style nodes from JS strings 'css-loader', // translates CSS into CommonJS 'less-loader', // compiles Less to CSS ] }, ] }, plugins: [ new BundleAnalyzerPlugin() ] }
打包結果:
效能圖:
構建時間:8.506s
這裡分析打包結果問題有哪些:
1.樣式檔案沒有剝離出來
2.node_modules被打進來了
3.第三方打包體積過大react,react-dom
4.檔案大小沒處理,沒有經過壓縮
好了針對以上幾個問題,我們重新配置webpack
1.剝離node_modules
rules: [ { test: /\.js$/, use: { loader: 'babel-loader', }, exclude: /node_modules/ }, { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, // 'style-loader',// 與 MiniCssExtractPlugin.loader 衝突 'css-loader' ], exclude: /node_modules/ }, { test: /\.less$/, use: [ MiniCssExtractPlugin.loader, // "style-loader", // creates style nodes from JS strings 'css-loader', // translates CSS into CommonJS 'less-loader', // compiles Less to CSS ], exclude: /node_modules/ }, { test: /\.(png|jpg|gif|svg|jpeg)$/, use: [ { loader: 'url-loader', options: { limit: 1000 * 100 } } ], exclude: /node_modules/ } ]
構建結果:
構建時間由8.506s變成1.251s
2.剝離js與css,less檔案
webpack4.X版本已經使用最新API mini-css-extract-plugin ,原來的extract-text-webpack-plugin在node版本為10.X以後已經失效了。
引入plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
配置loader
{ test: /\.css$/, use: [ MiniCssExtractPlugin.loader, // 'style-loader',// 與 MiniCssExtractPlugin.loader 衝突 'css-loader' ] }, { test: /\.less$/, use: [ MiniCssExtractPlugin.loader, // "style-loader", // creates style nodes from JS strings 'css-loader', // translates CSS into CommonJS 'less-loader', // compiles Less to CSS ] },
配置plugin
/** * 剝離CSS檔案 */ new MiniCssExtractPlugin({ filename: "[name].[chunkhash:8].css", chunkFilename: "[id].css" }), /** * 動態引入css,less,js等檔案 */ new HtmlWebpackPlugin({ title: 'webpack', template: './index.html' }),
重新build
構建時間有1.251s變成1.391s這裡剝離檔案導致構建時間增加,但是我們可以看到生成的目標js體積由987K變成了886K
3.分離第三方類庫 DllPlugin 和 DllReferencePlugin
首先建立webpack.dll.config.js
const webpack = require('webpack'); const path = require('path'); module.exports = { entry: { react: [ 'react', 'react-dom' ] }, output: { filename: '[name].dll.js', path: path.resolve('distDll/dll'), library: '[name]_dll_[hash]' }, plugins: [ new webpack.DllPlugin({ name: '[name]_dll_[hash]', path: path.join(__dirname, 'distDll/dll', '[name].manifest.json') }) ] }
在webpack.dev.js中增加
/** * 動態引入manifest.json */ new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./distDll/dll/react.manifest.json') }),
構建結果
構建時間1.391s變成1.008s 目標體積由886K變成了9.92K
4.利用快取加速二次構建
/** * 快取加速二次構建速度 */ new HardSourceWebpackPlugin({ cacheDirectory: 'node_modules/.cache/hard-source/[confighash]', configHash: function (webpackConfig) { // node-object-hash on npm can be used to build this. return require('node-object-hash')({ sort: false }).hash(webpackConfig); }, environmentHash: { root: process.cwd(), directories: [], files: ['package-lock.json', 'yarn.lock'], }, info: { // 'none' or 'test'. mode: 'none', // 'debug', 'log', 'info', 'warn', or 'error'. level: 'debug', }, cachePrune: { maxAge: 2 * 24 * 60 * 60 * 1000, sizeThreshold: 50 * 1024 * 1024 }, }),
構建結果:
可以看到有寫入快取的過程。這裡程式碼體積過小,沒看到加速效果,如果實際專案中,可以看到時間的縮小的效果
5.利用scope histing (變數提升) 減少程式碼閉包形成
這裡我使用了兩個測試檔案,a.js與b.js 其中b.js中引入了a.js
/** * 開啟 Scope Hoisting */ new webpack.optimize.ModuleConcatenationPlugin(),
配置前的效果:
可以清晰的看到打包之後的程式碼分別對a.js與b.js生成了兩個閉包函式(閉包函式的副作用這裡就不多說了,佔記憶體)
build出的檔案大小9.92K
配置後的效果:
可以看到效果已經沒有了針對兩個兩個js的閉包程式碼塊
我們可以看到目標檔案大小由9.92K變成了8.98K
6.Tree shaking 刪除沒用的函式或者變數
在.babelrc檔案中設定modules:false,其實webpack4中已經預設實現了tree shaking。
/* tree shaking. */ ["env", { "modules": false }],
我們在程式碼中加入一個無效函式
var treeShaking = function () { console.log('tree shaking.'); return; function unused() { return 'unused'; }; } treeShaking();
這裡需要修改build模式更改為生產環境(production)而不是開發環境(development)
效果:
可以看到已經消除了unused函式。
7.壓縮圖片檔案大小
{ test: /\.(png|jpg|gif|svg|jpeg)$/, use: [ 'url-loader', { loader: 'image-webpack-loader', // options: { // limit: 1000 * 100 //不加限制圖片過大會直接打到build下 導致找不到圖片檔案 // } options: { mozjpeg: { progressive: true, quality: 65 }, // optipng.enabled: false will disable optipng optipng: { enabled: false, }, pngquant: { quality: '65-90', speed: 4 }, gifsicle: { interlaced: false, }, // the webp option will enable WEBP webp: { quality: 75 } } } ], exclude: /node_modules/ }
壓縮後的效果:
由壓縮前的79.6K變成了72.5K
最終build出的效果圖
可以看到已經壓縮到了很小。
以上關於webpack的優化先總結到這裡,後續繼續更新。
github地址:https://github.com/Dqhan/Webpack