減少Webpack打包時間
1.優化Loader
對于Loader,影響打包效率的是它的屬性Babel.Babel會將代碼轉為字符串 生成AST,然后對AST繼續進行轉變最后生成新的代碼,項目越大,轉換代碼越多,效率就越低。
優化Loader的文件搜索范圍
module.exports = {
module:{
rules:[
{
//js文件才使用babel
test:/\.js$/,
loader:'babel-loader',
//只在src文件夾下查找
include:[resolve('src')],
//不會去查找的路徑
exclude:/node_modules/
}
]
}
}
把Babel編譯過的文件緩存起來
下次只需要編譯更改過的代碼文件即可
loader: 'babel-loader?cacheDirectory=ture'
HappyPack
因為Node是單線程運行的,所以Webpack在打包的過程中也是單線程的,特別是在執行Loader的時候,這樣會導致等待的情況
HappyPack可以將Loader的同步執行轉換為并行的
module:{
loader:[
{
//js文件才使用babel
test:/\.js$/,
//只在src文件夾下查找
include:[resolve('src')],
exclude:/node_modules/,
//id后面的內容對應下面
loader:'happypack/loader?id=happypack'
}
]
},
plugins:[
new HappyPack({
id:'happypack',
loaders:['babel-loader?cacheDirectory'],
//開啟4個線程
threads:4
})
]
DllPlugin
DllPlugin可以將特定的類庫提前打包然后引入。這種方式可以極大的減少打包類庫的次數,只有當類庫更新版本才有需要重新打包,并且也實現了將公共代碼抽離成單獨文件的優化方案
//單獨配置在一個文件里
//webpack.dll.conf.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry:{
//想統一打包的庫
vendor:['react']
},
output:{
path:path.join(__dirname,'dist'),
filename:'[name].dll.js',
library:'[name]-[hash]'
},
plugins:[
new webpack.DllPlugin({
//name必須和output.library一致
name:'[name]-[hash]',
//該屬性需要與DllReferencePlugin中一致
context:__dirname,
path:path.join(__dirname,'dist','[name]-mainfest.json')
})
]
}
然后需要執行這個配置文件生成依賴文件,接下來需要使用DllReferencePluhin將依賴文件引入項目中
//webpack.conf.js
module.exports={
//...省略其他配置
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
mainfest:require('./dist/vendor-mainfest.json')
})
]
}
減少Webpack打包后的文件體積
按需加載
如果我們把十幾個頁面甚至更多的路由頁面,把這些頁面全部打包進一個JS文件的話,雖然將多個請求合并了,但是同樣也加載了很多并不需要的代碼,耗費了更長的時間。那么為了首頁能更快地呈現給客戶,這時候我們就可以使用按需加載,將每個路由頁面單獨打包為一個文件,當然不僅路由可以按需加載,對于loadash這種大型類庫可以使用這個功能。
當使用的時候再去下載對應文件,返回一個Promise當Promise成功以后去執行回調
Scope Hoisting
Scope Hoisting會分析出模塊之間的依賴關系,盡可能的把打包出來的模塊合并到一個函數中去。
比如我們希望打包兩個模塊
//test.js
export const a=1
//index.js
import {a} from './test.js'
對于這種情況,我們打包出來的代碼類似這樣
[
function (module,exports,require){
//...
},
function(module,exports,require){
//...
}
]
但是如果我們使用Scope Hoisting的話,代碼就會盡可能的合并到一個函數去,也就變成了這樣的類似代碼
[
function(module,exports,require){
//...
}
]
這樣的打包方式生成的代碼明顯比之前的少了多了。如果在webpack4中希望開啟這個功能,只需要啟用
optimization.concatenateModules就可以了
module,exports={
optimization:{
concatenateModules:true
}
}
Tree Shaking
Tree Shaking 可以實現刪除項目中未被引用的代碼
//test.js
export const a = 1;
export const b = 2;
//index.js
import {a} from './test.js'
test文件中的變量b如果沒有在項目中使用到的話,就不會被打包到文件中。
webpack4的話,開啟生產環境就會自動啟動這個優化功能。