Reputation: 17365
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?
Upvotes: 8
Views: 2978
Reputation: 574
Try https://github.com/zhenyong/webpack-stable-module-id-and-hash which is appears to work fine.
first buid
js/app-379075f0ea0b0e0148f3.js 2.19 kB 0 [emitted] app
js/react-da22e98119ee46232ff7.js 747 kB 1 [emitted] react
rebuild, only app changed
js/app-fc7ca0df6dfcf7ca77f7.js 2.21 kB 0 [emitted] app
js/react-da22e98119ee46232ff7.js 747 kB 1 [emitted] react
Upvotes: 0
Reputation: 957
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.
Upvotes: 1