loader 設定include或者exclude
- 一般第三方包都是打包好的,無需再打包,特別是babel-loader、eslint-loader
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
}
複製程式碼
url-loader
- 可以將一些比較小的靜態檔案進行encode,轉成base64內聯。
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
// 小於10kb的會轉成base64
limit: 10 * 1024
}
}
複製程式碼
image-webpack-loader
- 使用image-webpack-loader進行圖片壓縮,可以和url-loader配合使用,先壓縮,然後小的轉base64
{
test: /\.(jpe?g|png|gif|svg)$/,
loader: 'image-webpack-loader',
// 保證在其他loader前進行處理
enforce: 'pre',
}
複製程式碼
externals
-
比如用到一些第三方庫,可以不通過webpack打包獲取,而且通過掛載在windows上、amd、commonjs等獲取
-
在做一些元件庫的按需載入時也是需要用到的
externals: {
'Vue': 'window.Vue',
'Vuex': 'window.Vuex',
// 或者是commonjs、amd
'Vue': {
commonjs: 'vue',
amd: 'vue'
}
}
複製程式碼
ModuleConcatenationPlugin
-
webpack 3新增的特性,用於將作用域提升,通過減少閉包的數量,能加快js的執行速度和一定程度減少體積
-
會增加編譯時間和破壞熱更新,所以只在生成環境使用
-
webpack4中引入
mode
概念,在生成環境中會自動開啟
plugins: [
new webpack.optimize.ModuleConcatenationPlugin()
]
複製程式碼
DefinePlugin
-
DefinePlugin將用"production"替換到process.env.NODE_ENV:
-
UglifyJS會移除掉所有if分支, 因為"production" !== 'production'永遠返回 false
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
})
]
複製程式碼
tree shaking
-
利用es module的靜態解析,移除無用依賴
-
babelrc中配置
modules: false
,讓babel不要處理import、export,讓webpack進行處理 -
webpack會在打包時標記無用程式碼,最後交給壓縮工具進行移除
-
更詳細的解釋可以看這裡
uglifyjs-webpack-plugin
- 支援
parallel
欄位,可以進行並行化構建,可以顯著加速構建
plugins: [
new UglifyJsPlugin({
parallel: true
})
]
複製程式碼
CommonsChunkPlugin
- 用於提取一些公共程式碼,一般是用於提取第三方庫,這個在上線部署時很有必要,因為出現bug,一般都是業務程式碼的問題,第三方庫相對比較穩定,這個時候第三方庫程式碼不應該受到影響,CommonsChunkPlugin可以減少熱更的代價
// 將第三方庫單獨打包成一個vender
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
})
複製程式碼
- 但是單獨抽離vender是不夠的,如果業務程式碼發生變化,還是會導致vender的hash值發生變化,快取的作用也隨著消失,解決這個問題需要再打一個包,一般命名manifest或者runtime
new webpack.optimize.CommonsChunkPlugin({
name: 'runtime',
// 無限大代表需要在所有的模組中共享的程式碼才會打包進來,意味著沒有任何模組打包進來,只有webpack的執行程式碼
minChunks: Infinity
})
複製程式碼
- webpack4中已經移除,使用optimization.splitChunks和optimization.runtimeChunk代替
NamedModulesPlugin
-
NamedModulesPlugin可以讓webpack打包時的chunk id變得穩定,如果我們手動新增一個依賴,會使得chunk id發生變化,這個外掛做的就是讓id穩定下來
-
webpack4中在開發模式中自動開啟(--mode development)
plugins: [
new NamedModulesPlugin()
]
複製程式碼
懶載入
-
webpack2以上支援動態import(),webpack1使用require.ensure,返回一個promise
-
webpack遇到import(),會單獨將其抽離成一個js檔案,等到執行時才去載入
-
一般用的多是在單頁面中,像vue-router、react-router等都支援import()進行懶載入
async function doSomeThing () {
const {default: moment} = await import('moment')
console.log(moment())
}
setTimeout(() => {
doSomeThing()
}, 1000)
複製程式碼
快取處理
-
一般情況下是讓伺服器新增相關的頭,比如
Cache-Control
或者Expires
-
也可以利用h5的manifest快取,可以做離線快取
-
可以利用
appcache-webpack-plugin
,即使處於離線狀態也是可以正常開啟網頁的,不過慢慢被淘汰,取而代之的是PWA
plugins: [
new AppCachePlugin({
network: ['*'], // No network access allowed!
output: 'cache.appcache'
}),
]
複製程式碼
// output
CACHE MANIFEST
# c5a4d08e79f57e7c0b18
/static/log26736681.png
/static/index.d156bde75c3265560b9b.js
/static/vendor.1fe523904e40ca0cfc76.js
/static/manifest.5969cefb99f458a69963.js
/static/index.5202b34274a8b8bad9c76962a800f30c.css
/static/../index.html
NETWORK:
*
複製程式碼
happypack、Dll和其他騷操作
- 可以看這裡