I'm attempting to use webpack to bundle my vendor scripts separately from my application scripts.
index.js
var _ = require('lodash');
console.log(_)
webpack.config.js
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var config = {
entry: {
vendor: ['lodash'],
app: './index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[chunkhash].js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: Infinity,
}),
new HtmlWebpackPlugin({
filename: 'index.html',
inject: true
})
]
};
module.exports = config;
results
Asset Size Chunks Chunk Names app.3437c5da57e0c6671675.js 145 bytes 0 [emitted] app vendor.72c95e21a8d7096d53bc.js 428 kB 1 [emitted] vendor index.html 232 bytes [emitted]
Now if I make a change to index.js
index.js
var _ = require('lodash');
console.log('changed index');
console.log(_)
results
Asset Size Chunks Chunk Names app.c724350371b50a9afeb2.js 177 bytes 0 [emitted] app vendor.0e76f9c86cbe02606265.js 428 kB 1 [emitted] vendor index.html 232 bytes [emitted]
Both hashes change even though I only updated the index file.
The difference between the two vendor files is
vendor.72c95e21a8d7096d53bc.js
script.src = __webpack_require__.p + "" + chunkId + "." + ({"0":"app"}[chunkId]||chunkId) + "." + {"0":"3437c5da57e0c6671675"}[chunkId] + ".js";
vendor.0e76f9c86cbe02606265.js
script.src = __webpack_require__.p + "" + chunkId + "." + ({"0":"app"}[chunkId]||chunkId) + "." + {"0":"c724350371b50a9afeb2"}[chunkId] + ".js";
After doing some research I found the article below which explains that webpack generates a chuck manifest that contains the chunk identifiers which is placed in the entry chunk. This explains the diff above. The solution is to extract the chuck manifest to a seperate file.
https://medium.com/@okonetchnikov/long-term-caching-of-static-assets-with-webpack-1ecb139adb95
index.js
var _ = require('lodash');
console.log(_)
webpack.config.js
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ChunkManifestPlugin = require('chunk-manifest-webpack-plugin');
var config = {
entry: {
vendor: ['lodash'],
app: './index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[chunkhash].js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: Infinity,
}),
new ChunkManifestPlugin({
filename: "manifest.json",
manifestVariable: "webpackManifest"
}),
new HtmlWebpackPlugin({
filename: 'index.html',
inject: true
})
]
};
module.exports = config;
results
Asset Size Chunks Chunk Names app.3437c5da57e0c6671675.js 145 bytes 0 [emitted] app manifest.json 35 bytes [emitted] vendor.72c95e21a8d7096d53bc.js 428 kB 1 [emitted] vendor
Now if I make a change to index.js
index.js
var _ = require('lodash');
console.log('changed index');
console.log(_)
results
Asset Size Chunks Chunk Names app.c724350371b50a9afeb2.js 177 bytes 0 [emitted] app manifest.json 35 bytes [emitted] vendor.0e76f9c86cbe02606265.js 428 kB 1 [emitted] vendor
Once again both hashes change even though I only updated the index file.
This time however, there are no differences between the two vendor files
Is there a reason why the above scenario is not working or am I fundamentally approaching this problem incorrectly.
Is there is an easier way with webpack to achieve what I'm trying to do, because even if I get the step above working, I'll have to read the manifest and then inject it into my index.html page?
Depending on the machine on which the build was launched, it tooks between 5 and 12 minutes. It is not possible to have a build that takes so long. webpack is not a slow bundler.
Builds are cached in node_modules/. cache/webpack by default but this can be customized using the cacheDirectory , cacheLocation , or name cache options.
Over the past eight years, webpack has become increasingly powerful. However, due to the additional packaging process, the building speed is getting slower as the project grows. As a result, each startup takes dozens of seconds (or minutes), followed by a round of build optimization.
Long term caching: It is to improve app loading time by keeping parts of the app on the client and avoid re-downloading them every time. Long term caching of your app assets is very important in improving load time.
It seems to be a problem with latest webpack version, please see open issue https://github.com/webpack/webpack/issues/1315
So for now you can't rely on [chunkhash], simplest solution is to use custom hash, something like <script src="vendor.js?v=001">
, and change it on backend every time when you releasing.
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