Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hash not change if change only chunk ids #2

Open
matpaul opened this issue Feb 13, 2017 · 10 comments
Open

Hash not change if change only chunk ids #2

matpaul opened this issue Feb 13, 2017 · 10 comments

Comments

@matpaul
Copy link

matpaul commented Feb 13, 2017

First of all thanks for your time! As i understand long term caching in webpack is big ass pain(

My prod setup pretty standard

plugins: [
        new WebpackChunkHash(),
        new HtmlWebpackPlugin({
            template: 'index.ejs',
            chunksSortMode: 'dependency'
        }),
        new HashedModuleIdsPlugin(),  
        new ExtractTextPlugin('css/app.[contenthash].css', {allChunks: true}),
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.optimize.CommonsChunkPlugin({
            names: ['vendor', 'manifest'],
            minChunks: Infinity
        }),
        new InlineManifestWebpackPlugin({
            name: 'webpackManifest'
        }),
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false,
                screw_ie8: true
            },
            comments: false
        })
]

I attach some screens for problem

Build 1
2017-02-14 0 26 54

Build 2
2017-02-14 0 30 16

And finally changes
2017-02-14 0 31 25

This is first file content changes (hash not change)
2017-02-14 0 33 44

So any help in this issue will be good

Thank you!

@matpaul
Copy link
Author

matpaul commented Feb 13, 2017

Also i use webpack v1 with hashedModulesIdsNames extracted from webpack v2, (can't switch to wp2) but i think this issue also reproduced in v2

@diestrin
Copy link

The issue is also happening on webpack2, I can confirm that. I have the exact same issue, and the problem is the id is not being included in the hash calculation, but it's really easy to solve.
I'll create a PR to fix this.

@diestrin
Copy link

Actually @matpaul , I just saw that the most updated version includes an option to pass a function and include the id by yourself

{
  additionalHashContent: chunk => chunk.id
}

@matpaul
Copy link
Author

matpaul commented Feb 16, 2017

@diestrin brilliant! Real awesome fix 👏
I think it should be default behavior

Update: =( I was inspired an idea that this should fix the issue, but after tests - nope =(
I have the same picture
screen shot 2017-02-17 at 10 16 11

So chunk id is not change - it's true
Changed only included chunks id

@matpaul
Copy link
Author

matpaul commented Feb 17, 2017

@diestrin @alexindigo
Okay, so the fix for my trouble was implement something like this

const chunkHashRecursion = (chunks, ids) => {
    const chunkIds = ids;

    chunks.forEach((chunk) => {
        chunkIds = chunkIds.concat(chunk.ids);
        if (chunks.length) {
            chunkHashRecursion(chunk.chunks, chunkIds);
        }
    });

    return chunkIds;
}

const filterAndSort => (array) => {
    return array
        .filter((item, pos) => array.indexOf(item) === pos)
        .sort((a, b) => a - b);
}

and setup plugin:

new WebpackChunkHash({
  additionalHashContent: (chunk) => {
    return filterAndSort(chunkHashRecursion(chunk.chunks, chunk.ids));
   }
})

It works, but as i see my vendor change hash because extracted manifest change id,
it's bad - is it possible to hardcode manifest id for example 0 always?

@SebastianS90
Copy link

@matpaul Have a look at here and here.
Looks like you can write a plugin that sets chunk-ids in the before-chunk-ids phase.

Slightly offtopic: We should compose a plugin that guarantees good caching:

  • Module ids will be set using the HashedModuleIdsPlugin
  • Chunk ids will be set as follows (assuming that a string is allowed as id):
    • entry point: their name
    • named chunks (require.ensure with 3rd parameter): their name
    • all other unnamed chunks: maybe we can calculate a hash over something that is mostly stable. If possible, we should avoid changing ids when two require.ensure (without 3rd parameter) are reordered.
  • Output files should be hashed using this plugin (with chunk ids part of the hashing). The additionalHashContent option can be used to append some configuration details (e.g. DefinePlugin) which will affect the outcome.

That would be more or less an improved version of the WebpackStableModuleIdAndHash webpack1 plugin.

@paneq
Copy link

paneq commented Mar 1, 2017

Related erm0l0v#7

@anilanar
Copy link

anilanar commented Oct 6, 2017

The following solution is wrong:

{
  additionalHashContent: chunk => chunk.id
}

The following solution is correctish:

{
  additionalHashContent: chunk => chunk.chunks.map(c => c.id).join(',')
}

You don't want a chunk's hash to change based on its id (consider named chunks). But you want its parent's hash to change.

@arthow4n
Copy link

setting { additionalHashContent: chunk => Array.from(chunk._modules).map(c => c.hash).join('') } worked for me.

@Tecayehuatl
Copy link

Have you tried using the webpack variable:

const webpack = require('webpack');

module.exports = {
    output: {
	path: path.resolve(__dirname, 'your_dist_path'),
	filename: '[name].[contenthash].js'
    },
    plugins: [
        new webpack.HashedModuleIdsPlugin()
    ],
    optimization: {
		runtimeChunk: 'single',
		splitChunks: {			
			chunks: 'all',
			maxInitialRequests: Infinity,
			minSize: 0,
			cacheGroups: {
				vendor: {
					test: /[\\/]node_modules[\\/]/,
					name(module) {
						const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
							return `npm.${packageName.replace('@', '')}`;
					  }
				}
			}
		}
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants