想要實時查看打包變化,能夠經過一個打包分析利器。webpack-bundle-analyzer
安裝javascript
npm i webpack-bundle-analyzer --save-dev
複製代碼
package.json裏面添加命令vue
"analyz": "NODE_ENV=production npm_config_report=true npm run build"
複製代碼
webpack配置java
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
plugins: [new BundleAnalyzerPlugin()],
複製代碼
執行node
npm npm run analyz
複製代碼
工具配置好以後webpack
首先看下webpack的默認打包配置web
module.exports = {
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
};
複製代碼
解析下參數npm
async表示只從異步加載得模塊(動態加載import())裏面進行拆分 initial表示只從入口模塊進行拆分 all表示以上二者都包括json
默認爲vendors和default。能夠設置權重值priority。緩存
vendor通常放置node_modules裏面的文件, default放置公共組件異步
咱們須要加添加幾個文件進行測試
可是如今個問題
假如我先創建一個btest文件,再創建一個atest文件,進行打包後,發現btest的文件的hash也會發生變化。
這是由於,webpack在創建依賴的時候的文件是按照ascall碼進行排序的,而後新插入的文件就會發生變化。
解決辦法,
給模塊的名字加上標識。這樣在打包的時候就會按照標識進行。 配置以下
optimization: {
namedChunks:true, //增長模塊標識
splitChunks: {
// 配置
}
},
plugins: [
new webpack.HashedModuleIdsPlugin(), //模塊增長標識,開發環境建議用 NamedModulePlugin
],
複製代碼
再進行打包,發現問題解決,再回到咱們的打包方案分析。
如今打包有幾種方案
1. node—modules和公共組件(好比loading)引用超過兩次以上都會打包到base文件。
webpack配置以下
optimization: {
splitChunks: {
cacheGroups: {
base:{
chunks: 'initial', //initial表示提取入口文件的公共部分
minChunks: 2, //表示提取公共部分最少的文件數
minSize: 0, //表示提取公共部分最小的大小
name: 'base' //提取出來的文件命名
}
}
}
},
複製代碼
打包分析結果以下
<template>
<div>
atest
</div>
</template>
<script>
import Loading from '../components/loading/loading' //引入Loading組件
export default {
}
</script>
複製代碼
再次打包
2. 分離式打包,node_modules會單獨打包,每一個引入的組件會打包到一個文件中。 webpack配置以下
optimization: {
namedChunks:true,
splitChunks: {
chunks: 'all',
minSize: 0,
minChunks: 1,
maxAsyncRequests: 10,
maxInitialRequests: 10,
// automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
minChunks: 1,
test: /[\\/]node_modules[\\/]/,
priority: -10 // 權重
},
default: {
minChunks: 1,
priority: -20, // 權重
reuseExistingChunk: true
}
}
}
},
複製代碼
設置兩個緩存組:其中vendors是放node_modules打包後的文件
老樣子,添加atest文件和btest文件
打包分析
<div>
atest
</div>
</template>
<script>
import myCom from '../components/testCom/testCom'
export default {
}
</script>
複製代碼
打包分析
vendors: {
minChunks: 1,
test: /[\\/]node_modules[\\/]/,
priority: -10, // 權重
minSize: 0,
},
base: {
priority: -20, // 權重
chunks: 'initial', //initial表示提取入口文件的公共部分
minChunks: 1, //表示提取公共部分最少的文件數
minSize: 0, //表示提取公共部分最小的大小
name: '
}
複製代碼
來看下打包結果
先上代碼
vendors: {
name:'vendors',
minChunks: 1,
test: /[\\/]node_modules[\\/]/,
priority: -10, // 權重
minSize: 0,
},
default:{
test:/[\\/]components[\\/]|[\\/]common[\\/]/,
priority:-20, // 權重
name(module){
// console.log('模塊分析打印')
// console.log(module.identifier())
const moduleFileName = module
.identifier()
.split('/')
.pop()
.replace('.js','')
return `${moduleFileName}`
}
},
複製代碼
其中的components是我存放公共組件的地方,common是存放公共js方法的地方。我只須要篩選他們下面的引入
打包結果以下
<template>
<div>
atest
</div>
</template>
<script>
import myCom from '../components/testCom/testCom'
import '../common/widget/common'
export default {
}
</script>
複製代碼
在看打包結果
這樣比較上面方式的好處是,上面那種方法,當你只改變一個組件的內容時候,會引發整個base的變化。這個弊端會隨着base文件的愈來愈大而愈來愈️明顯
最後放一下三種方案的代碼
1. node—modules和公共組件(好比loading)引用超過兩次以上都會打包到base文件。
optimization: {
namedChunks: true,
splitChunks: {
chunks: 'all',
minSize: 0,
minChunks: 1,
maxAsyncRequests: 100,
maxInitialRequests: 100,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
base: {
minChunks: 1, //表示提取公共部分最少的文件數
minSize: 0, //表示提取公共部分最小的大小
name: 'base' //提取出來的文件命名
}
}
}
複製代碼
2. 分離式打包,node_modules會單獨打包,每一個引入的組件也會單獨打包。
optimization: {
namedChunks: true,
splitChunks: {
chunks: 'all',
minSize: 0,
minChunks: 1,
maxAsyncRequests: 100,
maxInitialRequests: 100,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
minChunks: 1,
test: /[\\/]node_modules[\\/]/,
priority: -10, // 權重
minSize: 0,
},
base: {
priority: -20, // 權重
chunks: 'initial', //initial表示提取入口文件的公共部分
minChunks: 1, //表示提取公共部分最少的文件數
minSize: 0, //表示提取公共部分最小的大小
name: 'base' //提取出來的文件命名
}
}
}
複製代碼
3. 所有打散式打包,node_modules會打成包,每一個組件本身單獨打包。
optimization: {
namedChunks: true,
splitChunks: {
chunks: 'all',
minSize: 0,
minChunks: 1,
maxAsyncRequests: 100,
maxInitialRequests: 100,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
name:'vendors',
minChunks: 1,
test: /[\\/]node_modules[\\/]/,
priority: -10, // 權重
minSize: 0,
},
default:{
test:/[\\/]components[\\/]|[\\/]common[\\/]/,
priority:-20, // 權重
name(module){
// console.log('模塊分析打印')
// console.log(module.identifier())
const moduleFileName = module
.identifier()
.split('/')
.pop()
.replace('.js','')
return `${moduleFileName}`
}
}
}
}
複製代碼