好比說通用的日期庫是moment.js,這個庫會佔用很大的體積,由於當引用這個庫的時候,全部的locale文件都被引入,而這些文件甚至在整個庫的體積中佔了大部分, 要想對此進行優化必須在webpack打包時移除這部份內容
webpack自帶的IgnorePlugin插件便會處理進行優化
javascript
plugins:[
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]複製代碼
以上配置忽略了時間格式化moment.js中的語言包
java
優化前node
優化後react
咱們在引入lodash這種重型的js庫的時候,咱們可能只須要引用裏面部分函數,可是當咱們所有引入打包lodash.js體積就會很龐大webpack
優化前es6
import _ from 'lodash';
console.log(_.map)
//ƒ map(collection,iteratee){var func=isArray(collection)?arrayMap:baseMap;return func(collection,getIteratee(iteratee,3));}複製代碼
可是咱們若是按需導入 這樣就會減小很大致積web
優化後json
import map from 'lodash/map';
console.log(map)
//ƒ map(collection, iteratee) {
var func = isArray(collection) ? arrayMap : baseMap;
return func(collection, baseIteratee(iteratee, 3));
}複製代碼
設置解析文件後綴,能夠加速文件尋找速度
resolve: {
extensions: ['.js', '.json', 'jsx']
}複製代碼
resolve: {
// 使用絕對路徑指明第三方模塊存放的位置,以減小搜索步驟
modules: [path.resolve(__dirname,'node_modules')]
}複製代碼
因爲Loader對文件的轉換操做很耗時,因此須要讓儘量少的文件被Loader處理。咱們能夠經過如下3方面優化Loader配置:
(1)優化正則匹配
(2)經過cacheDirectory選項開啓緩存
(3)經過include、exclude來減小被處理的文件。
module: {
rules: [
{
test:/\.js$/,
//babel-loader支持緩存轉換出的結果,經過cacheDirectory選項開啓
loader:'babel-loader?cacheDirectory',
//只對項目根目錄下的src 目錄中的文件採用 babel-loader
include: [path.resolve('src')],
//排除 node_modules 目錄下的文件,node_modules 目錄下的文件都是採用的 ES5 語法,不必再經過 Babel 去轉換
exclude: path.resolve(__dirname, 'node_modules')
}
]
}複製代碼
Webpack 4 移除了 CommonsChunkPlugin取而代之的是兩個新的配置項 optimization.splitChunks 和 optimization.runtimeChunk。
redux
CommonsChunkPlugin
緩存
webpack 將多個模塊打包以後的代碼集合稱爲 chunk。爲了將一些不多變化的經常使用庫(react、redux、lodash)與業務代碼分開,或者是一些不一樣入口共同使用的公共模塊,開發者經常須要將它們單獨打包,這些均可以經過配置 CommonsChunkPlugin 來實現。
entry: {
app:'./main.js',
vendor: ['react','react-dom']
},
plugins:
new webpack.optimize.CommonsChunkPlugin({names:['vendor']})
]
複製代碼
webpack 4 準備經過 optimization.splitChunks 和 optimization.runtimeChunk 屬性來簡化代碼分割的配置
optimization.splitChunks
經過設置 optimization.splitChunks.chunks: "all" 來啓動默認的代碼分割配置項。
當知足以下條件時,webpack 會自動打包 chunks:
1)當前模塊是公共模塊(多處引用)或者模塊來自 node_modules
2)當前模塊大小大於 30kb 若是此模塊是按需加載,並行請求的最大數量小於等於 5
3)若是此模塊在初始頁面加載,並行請求的最大數量小於等於 3
optimization: {
splitChunks: {
chunks: 'all',
name: true,
automaticNameDelimiter: '-', // 模塊間的鏈接符,默認爲"~"
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10 // 優先級,越小優先級越高
},
default: { // 默認設置,可被重寫
minChunks: 2,
priority: -20,
reuseExistingChunk: true // 若是原本已經把代碼提取出來,則重用存在的而不是從新產生
}
}
}
}複製代碼
因爲有大量文件須要解析和處理,構建是文件讀寫和計算密集型的操做,特別是當文件數量變多後,Webpack 構建慢的問題會顯得嚴重。
運行在 Node.js 之上的 Webpack 是單線程模型的,也就是說 Webpack 須要處理的任務須要一件件挨着作,不能多個事情一塊兒作。 文件讀寫和計算操做是沒法避免的,那能不能讓 Webpack 同一時刻處理多個任務,HappyPack 就能讓 Webpack 作到這點,它把任務分解給多個子進程去併發的執行,子進程處理完後再把結果發送給主進程。
當同時讀取多個loader文件資源時,好比`babel-loader`須要 transform 各類jsx,es6的資源文件。在這種同步計算同時須要大量耗費 cpu 運算的過程當中,node的單進程模型就無優點了,而 Happypack 就是針對解決此類問題而生的存在
const HappyPack = require('happypack');
module: { rules: [
{
test:/\.js/,
//loader:'babel-loader',
include: [path.resolve('src')],
// 排除 node_modules 目錄下的文件,node_modules 目錄下的文件都是採用的 ES5 語法,不必再經過 Babel 去轉換
exclude: path.resolve(__dirname, 'node_modules'),
// 把對 .js 文件的處理轉交給 id 爲 babel 的 HappyPack 實例
loader: 'happypack/loader?id=babel'
}
]
},
plugins:[ new HappyPack({
// 用惟一的標識符 id 來表明當前的 HappyPack 是用來處理一類特定的文件
id: 'babel',
// 如何處理 .js 文件,用法和 Loader 配置中同樣
loaders: ['babel-loader?cacheDirectory'],
// ... 其它配置項
})
]
複製代碼
未完待續................