構建優(yōu)化
縮小文件搜索范圍
優(yōu)化 loader 配置
通過test
编振、include
、exclude
三個配置項毙驯,減少loader處理的文件
優(yōu)化 resolve.modules 配置
當安裝的第三方模塊都放在項目根目錄下的./node_modules
目錄下時稽坤,沒有必要按照默認的方式去一層層的尋找,可以指明存放第三方模塊的絕對路徑线得,以減少尋找。
module.exports = {
resolve: {
// 使用絕對路徑指明第三方模塊存放的位置徐伐,以減少搜索步驟
// 其中 __dirname 表示當前工作目錄贯钩,也就是項目根目錄
modules: [path.resolve(__dirname, 'node_modules')]
},
};
優(yōu)化 module.noParse 配置
module.noParse
配置項可以讓 Webpack 忽略對部分沒采用模塊化的文件的遞歸解析處理,這樣做的好處是能提高構建性能办素。
module.exports = {
module: {
// index.html中外部鏈接引入的文件
noParse: [/jquery|lodash/],
},
};
使用 HappyPack
在整個 Webpack 構建流程中角雷,最耗時的流程可能就是 Loader 對文件的轉換操作了,因為要轉換的文件數(shù)據(jù)巨多摸屠,而且這些轉換操作都只能一個個挨著處理谓罗。 HappyPack 的核心原理就是把這部分任務分解到多個進程去并行處理,從而減少了總的構建時間季二。
安裝依賴
npm i -D happypack
接入配置
const HappyPack = require('happypack');
const os = require('os'); // node 提供的系統(tǒng)操作模塊
// 構造出共享進程池,根據(jù)我的系統(tǒng)的內(nèi)核數(shù)量 指定線程池個數(shù) 也可以其他數(shù)量
const happyThreadPool = HappyPack.ThreadPool({size: os.cpus().length});
module.exports = {
module: {
rules: [
{
test: /\.js$/,
// 把對 .js 文件的處理轉交給 id 為 babel 的 HappyPack 實例
use: ['happypack/loader?id=babel'],
// 排除 node_modules 目錄下的文件揭措,node_modules 目錄下的文件都是采用的 ES5 語法胯舷,沒必要再通過 Babel 去轉換
exclude: path.resolve(__dirname, 'node_modules'),
},
{
// 把對 .css 文件的處理轉交給 id 為 css 的 HappyPack 實例
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: ['happypack/loader?id=css'],
}),
},
]
},
plugins: [
new HappyPack({
// 用唯一的標識符 id 來代表當前的 HappyPack 是用來處理一類特定的文件
id: 'babel',
// 如何處理 .js 文件,用法和 Loader 配置中一樣
loaders: ['babel-loader?cacheDirectory'],
// 使用共享進程池中的子進程去處理任務
threadPool: happyThreadPool,
}),
new HappyPack({
id: 'css',
// 如何處理 .css 文件绊含,用法和 Loader 配置中一樣
loaders: ['css-loader'],
// 使用共享進程池中的子進程去處理任務
threadPool: happyThreadPool,
})
],
};
使用 ParallelUglifyPlugin
由于壓縮 JavaScript 代碼需要先把代碼解析成用 Object 抽象表示的 AST 語法樹桑嘶,再去應用各種規(guī)則分析和處理 AST,導致這個過程計算量巨大躬充,耗時非常多逃顶。
當 Webpack 有多個 JavaScript 文件需要輸出和壓縮時,原本會使用 UglifyJS 去一個個挨著壓縮再輸出充甚, 但是 ParallelUglifyPlugin 則會開啟多個子進程以政,把對多個文件的壓縮工作分配給多個子進程去完成,每個子進程其實還是通過 UglifyJS 去壓縮代碼伴找,但是變成了并行執(zhí)行盈蛮。 所以 ParallelUglifyPlugin 能更快的完成對多個文件的壓縮工作。
npm i -D webpack-parallel-uglify-plugin
const path = require('path');
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
module.exports = {
plugins: [
// 使用 ParallelUglifyPlugin 并行壓縮輸出的 JS 代碼
new ParallelUglifyPlugin({
//開啟幾個子進程去并發(fā)的執(zhí)行壓縮技矮。默認是當前運行電腦的 CPU 核數(shù)減去1抖誉。
workerCount: 4,
// 傳遞給 UglifyJS 的參數(shù)
uglifyJS: {
output: {
// 最緊湊的輸出
beautify: false,
// 刪除所有的注釋
comments: false,
},
compress: {
// 在UglifyJs刪除沒有用到的代碼時不輸出警告
warnings: false,
// 刪除所有的 `console` 語句殊轴,可以兼容ie瀏覽器
drop_console: true,
// 內(nèi)嵌定義了但是只用到一次的變量
collapse_vars: true,
// 提取出出現(xiàn)多次但是沒有定義成變量去引用的靜態(tài)值
reduce_vars: true,
}
},
}),
],
};
輸出質(zhì)量優(yōu)化
使用imagemin-webpack-plugin插件
import ImageminPlugin from 'imagemin-webpack-plugin'
module.exports = {
plugins: [
// Make sure that the plugin is after any plugins that add images
new ImageminPlugin({
disable: process.env.NODE_ENV !== 'production', // Disable during development
test: /\.(gif|png|jpe?g|svg)$/i,
onlyUseIfSmaller: true,
pngquant: {
quality: '65-80'
}
})
]
}
chainWebpack
配置
import ImageminWebpackPlugin from 'imagemin-webpack-plugin';
module.exports = {
chainWebpack: config => {
config.plugin('imagemin-webpack-plugin')
.use(ImageminWebpackPlugin, [
{
disable: process.env.NODE_ENV !== 'production'
test: /\.(gif|png|jpe?g|svg)$/i,
onlyUseIfSmaller: true,
pngquant: {
quality: '65-80'
}
}
]);
}
}
提取公共代碼
將所有從node_modules
的引用打包到一個名字叫vendor的chunk
module.exports = {
//...
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};