We have a traditional server rendered application (non SPA) where each page is augmented with vuejs
Our existing webpack 3 configuration is
webpack.config.js
var webpack = require('webpack')
var path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
entry: {
shared: './shared.js',
pageA: './pageA.js',
// pageB: './pageB.js',
// pageC: './pageC.js',
// etc
},
resolve: {
alias: { vue: 'vue/dist/vue.esm.js' },
},
output: {
path: path.join(__dirname, './dist'),
filename: '[name].js',
},
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
query: {
sourceMap: true,
},
},
],
}),
},
],
},
plugins: [
new CleanWebpackPlugin('./dist'),
new webpack.optimize.CommonsChunkPlugin({
name: ['shared'],
minChunks: Infinity,
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'runtime',
}),
new ExtractTextPlugin('[name].css'),
new CopyWebpackPlugin([{ from: 'index.html', to: '.' }]),
],
}
shared.js
// import shared dependencies & pollyfills
var vue = require('vue')
// import global site css file
require('./shared.css')
// initialize global defaults
// vue.setDefaults(...)
console.log('shared', { vue })
pageA.js
var vue = require('vue')
// only this page uses axios
var axios = require('axios')
console.log('pageA', { vue, axios })
shared.css
body {
background-color: aquamarine;
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<!-- included on every page-->
<link rel="stylesheet" href="shared.css">
</head>
<body>
<!-- included on every page-->
<script src="runtime.js"></script>
<script src="shared.js"></script>
<script src="pageA.js"></script>
</body>
</html>
With this setup
1) runtime.js
contains the webpack loader, so any changes to shared.js
don't cause pageA.js
to be cache busted and vice versa
2) shared.js
contains any shared dependencies (in this case vue
) as well as any shared global initializion for every page (setting vue
defaults etc). It is also the point we import our shared global css file.
3) pageA.js
does not contain any dependencies imported in shared.js
(vue
in this case) but does contain dependicies it imports (axios
in this case).
We have been unable to reproduce this setup using the SplitChunksPlugin
1) SplitChunksPlugin
doesn't seem to allow an entry point as a split point.
2) All the examples have split out ALL node module dependices into a vendor chunk. This doesn't work for us as we have 100's of pages but only a few import a graphing library or moment etc... We don't want to have this graphing library or moment included in shared.js
as it will then be load for all pages.
3) It wasn't clear how to split the runtime into its own file either
SplitChunksPlugin
seems to be targeted at SPA's where javascript can be loaded on demand. Is the scenario we are trageting still supported?
Are you trying to migrate to webpack 4?
I find the optimisation cacheGroups test option
works well to be specific about what goes where.
optimization: {
splitChunks: {
cacheGroups: {
shared: {
test: /node_modules[\\/](?!axios)/,
name: "shared",
enforce: true,
chunks: "all"
}
}
}
}
Will load everything from the node modules (except axios) and should therefore be included as part of your page entry point.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With