移除外掛某些包,減少外掛體積
比如說通用的日期庫是moment.js,這個庫會佔用很大的體積,因為當引用這個庫的時候,所有的locale檔案都被引入,而這些檔案甚至在整個庫的體積中佔了大部分, 要想對此進行優化必須在webpack打包時移除這部分內容
webpack自帶的IgnorePlugin外掛便會處理進行優化
plugins:[
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]複製程式碼
以上配置忽略了時間格式化moment.js中的語言包
優化前
優化後
模組化引入 按需匯出
我們在引入lodash這種重型的js庫的時候,我們可能只需要引用裡面部分函式,但是當我們全部引入打包lodash.js體積就會很龐大
優化前
import _ from 'lodash';
console.log(_.map)
//ƒ map(collection,iteratee){var func=isArray(collection)?arrayMap:baseMap;return func(collection,getIteratee(iteratee,3));}複製程式碼
但是我們如果按需匯入 這樣就會減少很大體積
優化後
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配置 設定解析檔案字尾
設定解析檔案字尾,可以加速檔案尋找速度
resolve: {
extensions: ['.js', '.json', 'jsx']
}複製程式碼
優化resolve.modules配置
resolve.modules 用於配置Webpack去哪些目錄下尋找第三方模組。resolve.modules的預設值是[node modules],含義是先去當前目錄的/node modules目錄下去找我們想找的模組,如果沒找到,就去上一級目錄../node modules中找,再沒有就去../ .. /node modules中找,以此類推,這和Node.js的模組尋找機制很相似。當安裝的第三方模組都放在專案根目錄的./node modules目錄下時,就沒有必要按照預設的方式去一層層地尋找,可以指明存放第三方模組的絕對路徑,以減少尋找。
resolve: {
// 使用絕對路徑指明第三方模組存放的位置,以減少搜尋步驟
modules: [path.resolve(__dirname,'node_modules')]
}複製程式碼
優化loader配置 縮小檔案搜尋範圍
由於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')
}
]
}複製程式碼
optimization.splitChunks 提取公共程式碼
Webpack 4 移除了 CommonsChunkPlugin取而代之的是兩個新的配置項 optimization.splitChunks 和 optimization.runtimeChunk。
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 // 如果本來已經把程式碼提取出來,則重用存在的而不是重新產生
}
}
}
}複製程式碼
用 Happypack 來加速程式碼構建
由於有大量檔案需要解析和處理,構建是檔案讀寫和計算密集型的操作,特別是當檔案數量變多後,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'],
// ... 其它配置項
})
]
複製程式碼
未完待續................