purpose
Vue is packaged in a single file. The size of vendor is too large, which affects page performance. Vue related (vue, vuex, vue-Router), element-ui, echarts (echarts, zrender) are extracted as separate JS files to reduce vendor size. At the same time, pulling out modules that are less likely to change also has some benefit for version iteration of the project (avoiding unnecessary file hash changes that result in re-requests for data).
Begin to dig a hole
Vue scaffolding default commonsChunkPlugin configuration:
// ./build/webpack.prod.conf.js
const webpackConfig = merge(baseWebpackConfig, {
...
plugins: [
...
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (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)}}),new webpack.optimize.CommonsChunkPlugin({
name: 'manifest'.minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'app'.async: 'vendor-async'.children: true.minChunks: 3}),... ] });Copy the code
The default configuration here is to remove all public plug-ins from vendor and webpack-related runtime modules from manifest from a single entry: App (Entry Chunk).
The initial renovation is as follows:
// Remove required module data from vendor
new webpack.optimize.CommonsChunkPlugin({
name: 'echarts'.chunks: ['vendor'],
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/echarts|zrender/.test(module.resource)
)
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'element-ui'.chunks: ['vendor'],
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/element-ui/.test(module.resource)
)
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vue'.chunks: ['vendor'],
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/vue/.test(module.resource)
)
}
}),
Copy the code
With the above code, packaging does take the element- UI, Echarts, and Vue out of the equation:
The webpackJsonp is not defined, as you can imagine, the running environment after the WebPack is packaged is faulty, according to the official website
The CommonsChunkPlugin is used to run the webpack. The code is split into the manifest.
- The manifest packaging error
- Not Defined is common in normal development work, and the runtime webpackJsonp is not defined
In conjecture 1, since only the chunk corresponding to the regular is removed from the vendor, it hardly affects the pulling out of the running environment of Webpack, so obviously the probability of error is very small.
Most likely a guess 2 question, check out the packaged index.html file
Compare this to the index.html in our other (normal) environment
Obviously, the order of script calls to manifest.js has changed so that webpackJsonp is not defined, so we need to change the order in which chunks are written to index.html
Writing chunks is the job of the HtmlWebpackPlugin
Vue scaffolding out, default configuration:
// webpack.prod.conf.js
new HtmlWebpackPlugin({
...
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
Copy the code
ChunksSortMode: allows controlling the ordering of chunks before inserting HTML
Allows to control how chunks should be sorted before they are included to the HTML. Allowed values are 'dependency' | 'none' | 'auto' | 'manual' | {Function}
Copy the code
‘dependency’ : sorting by file dependencies, not available above version 4.0 ‘auto’ : default ‘none’ ‘manual’ : custom sorting
ChunksSortMode: ‘dependency’ : / / dependency = ‘dependency’; / / dependency = ‘dependency’;
Note that app.js depends on other plug-ins and library files, so it must be loaded last, otherwise it will cause a lot of not defined errors
// webpack.prod.conf.js
new HtmlWebpackPlugin({
...
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'manual'.chunks: ['manifest'.'vendor'.'vue'.'element-ui'.'echarts'.'app']}),Copy the code
The packed files are in order:
Then put into the test environment, it can run normally….
Doubts point
What is a bit odd is that, on the day before, I put it into the test environment according to the above configuration, there will be the following error (the chart here is a screenshot of a similar error, which are both ‘call’ of underpay ‘in the manifester.js)
I added the following code because I thought the manifest chunks were incomplete
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest'.chunks: ['vendor'.'vue'.'element-ui'.'echarts'.'app'].minChunks: Infinity
}),
Copy the code
Magically no problem QAQ
Then the next day to remove the code and repackage, but without the above problem, you big guys have any good ideas?
Compare splitChunks briefly
The default configuration of VUE-CLI3 for splitChunks is:
// code splitting
if(process.env.NODE_ENV ! = ='test') {
webpackConfig
.optimization.splitChunks({
cacheGroups: {
vendors: {
name: `chunk-vendors`.test: /[\\/]node_modules[\\/]/.priority: - 10.chunks: 'initial'
},
common: {
name: `chunk-common`.minChunks: 2.priority: - 20.chunks: 'initial'.reuseExistingChunk: true}}})}Copy the code
In vue. Config. js, the separation of element-UI and vue is very simple, mainly dealing with priority
module.exports = {
...
chainWebpack: config= > {
// code splitting
config.optimization.splitChunks({
cacheGroups: {
vendors: {
name: `chunk-vendors`.test: /[\\/]node_modules[\\/]/.priority: - 10.chunks: 'initial'
},
common: {
name: `chunk-common`.minChunks: 2.priority: - 20.chunks: 'initial'.reuseExistingChunk: true
},
// Separate out the element-ui
element: {
name: `element-ui`.test: /element-ui/.priority: 10.chunks: 'all'
},
// Separate vUe-related items
vue: {
name: `vue`.test: /vue/.priority: 20.chunks: 'all'}}}); }};Copy the code
The CommonsChunkPlugin is very simple.
The above is just a little opinion, if there is a mistake, don’t hesitate to give advice !!!!!