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

Use WebpackMD5Hash and ChunkManifestPlugin? #210

Closed
gaearon opened this issue Jul 26, 2016 · 27 comments
Closed

Use WebpackMD5Hash and ChunkManifestPlugin? #210

gaearon opened this issue Jul 26, 2016 · 27 comments

Comments

@gaearon
Copy link
Contributor

gaearon commented Jul 26, 2016

https://github.com/mjackson/web-starter has some interesting config decisions:

  • Use of WebpackMD5Hash plugin
  • Use of ChunkManifestPlugin plugin

I’d like to understand their point better and whether we should enable them as well.
Thoughts?

@insin
Copy link
Contributor

insin commented Jul 26, 2016

Relevant webpack issue:

webpack/webpack#1315

Relevant Twitter threads on this implementation:

@gaearon
Copy link
Contributor Author

gaearon commented Jul 26, 2016

OK, this looks reasonable. Would you like to make a PR to get this in?

@mjackson
Copy link
Contributor

I wasn't able to get long-term hashing working correctly w/out using WebpackMD5Hash and ChunkManifestPlugin. The problem was that my hashes kept changing on every single deploy. The reason was that, when you're doing long-term caching, the webpack manifest has a new hash every time. But if that hash is also in your bundle, then the hash of your bundle changes too. It's a circular problem.

The solution is to extract your webpack manifest and stick it in the HTML, which is what ChunkManifestPlugin does. However, you need to be able to control rendering the HTML so you can put the webpack manifest in there.

@ForbesLindesay
Copy link
Contributor

You could also stick the manifest in a separate JavaScript file. You could even then add a hash to the manifest as long as the manifest file itself doesn't get included in the manifest (creating your cycle).

@mjackson
Copy link
Contributor

Yep, you can put it in a separate file. Putting it in the HTML just avoids the extra HTTP request.

@ForbesLindesay
Copy link
Contributor

You could even concatenate it on the start of your existing JS file after the hash is generated (this may have to be done outside of webpack, I don't know much about webpack's features)

@gaearon
Copy link
Contributor Author

gaearon commented Jul 26, 2016

Or we can take control of rendering the HTML.
Maybe HTMLWebpackPlugin already exposes some hooks for that.

@insin
Copy link
Contributor

insin commented Jul 26, 2016

You can use inline-manifest-webpack-plugin to make an extracted manifest available to inline in a <script> tag in your HtmlWebpackPlugin template.

You can also write another plugin to automatically insert this into the HTML before HtmlWebpackPlugin injects HTML into the template for generated files.

Example in this issue: szrenwei/inline-manifest-webpack-plugin#5

Might just be easier to write your own plugin which does all of that in one place.

@gaearon
Copy link
Contributor Author

gaearon commented Jul 26, 2016

Haha, I was just trying that. After completely reading through webpack/webpack#1315 I can certainly empathize with frustrations around JavaScript tooling.

@gaearon
Copy link
Contributor Author

gaearon commented Jul 26, 2016

OK, now I have a JS object in my HTML. How am I supposed to use this correctly?

screen shot 2016-07-26 at 18 39 22

I’m trying

    new webpack.optimize.CommonsChunkPlugin({
      names: ['react', 'manifest']
    }),
    new WebpackMd5HashPlugin(),
    new InlineManifestPlugin(),
    function injectManifestIntoHTML() {
      this.plugin('compilation', (compilation) => {
        compilation.plugin('html-webpack-plugin-before-html-processing', (data, cb) => {
          data.html = data.html.replace('</body>', data.assets.webpackManifest + '</body>');
          cb()
        })
      })
    },
    new HtmlWebpackPlugin({
      // ...

right now.

@jfrolich
Copy link

jfrolich commented Jul 27, 2016

It's definitely suboptimal, long term caching seems to be a top priority if you deploy often. Almost lost a day fixing this, found the solution thanks to @mjackson (thanks!).

@gaearon You have to assign it to window.webpackManifest so just add

window.webpackManifest = {...}

@mjackson
Copy link
Contributor

Almost lost a day fixing this

I lost 1.5 days last week ;)

@mxstbr
Copy link
Contributor

mxstbr commented Jul 29, 2016

I FINALLY FIGURED OUT HOW TO DO LONG-TERM CACHING WITHOUT DOING WEIRD STUFF!!! kentcdodds/es6-todomvc@4dcfaa9

@kentcdodds (src: https://twitter.com/kentcdodds/status/759078941206261761)

Possibly helpful?

@kentcdodds
Copy link
Contributor

Yeah, basically you take inline-manifest-webpack-plugin + html-webpack-plugin and it just kinda magically works :)

@mxstbr
Copy link
Contributor

mxstbr commented Jul 29, 2016

IIRC that sounds exactly like the kinda thing @gaearon struggled with?

@kentcdodds
Copy link
Contributor

Yeah, I don't think you need to do all the stuff that @mjackson is doing because you're already using the html-webpack-plugin so basically just do the same things I'm doing in my diff and you should have it 👍

@gaearon
Copy link
Contributor Author

gaearon commented Jul 29, 2016

This requires <%=htmlWebpackPlugin.files.webpackManifest%> which is not something I want to expose to the user. Can we put it there automatically somehow?

@kentcdodds
Copy link
Contributor

If I've learned anything about webpack, the answer is always yes. It's just a matter of how :)

I'm not certain I understand your hesitance to put it in the index.html. My first thought would be that you want to hide away any magic from the user (especially when they eject), but you've already got magic as part of the setup because the html-webpack-plugin auto-inserts the needed script tags. I realize that this is a little different, but I personally don't see a problem with adding it.

However, if someone else has a way to avoid adding it at all, that'd be pretty sweet. I imagine there's a way.

@insin
Copy link
Contributor

insin commented Jul 29, 2016

I've got this down to 4 plugins, automatically injecting the manifest into the generated HTML:

Plugins & reason for each one: https://github.com/insin/nwb/blob/next/src/createWebpackConfig.js#L366-L379

Custom plugin to inject the manifest and stop it from being emitted: https://github.com/insin/nwb/blob/545c9a2581ecce55ec6416af16d1154d86f48c7a/src/createWebpackConfig.js#L244-L272

@gaearon
Copy link
Contributor Author

gaearon commented Jul 29, 2016

I'm not certain I understand your hesitance to put it in the index.html. My first thought would be that you want to hide away any magic from the user (especially when they eject), but you've already got magic as part of the setup because the html-webpack-plugin auto-inserts the needed script tags. I realize that this is a little different, but I personally don't see a problem with adding it.

If it’s there, somebody’s going to delete it by mistake.
Also a mix of “injecting some stuff and not the other stuff” is confusing.

@gaearon
Copy link
Contributor Author

gaearon commented Jul 29, 2016

@insin Should Md5HashPlugin be necessary if we have HashedModuleIdsPlugin?

@kennetpostigo
Copy link

Came across this on Medium and might be useful.

@insin
Copy link
Contributor

insin commented Jul 30, 2016

Should Md5HashPlugin be necessary if we have HashedModuleIdsPlugin?

HashedModuleIdsPlugin is to prevent module ids changing across builds by not depending on Webpack assigning integer ids in a particular order each time, without having to store anythhing between builds.

Md5HashPlugin just happens to make [chunkhash] (which changes if you're extracting CSS from the same chunk) behave like [contenthash] - now I think of it if there was default [contenthash] config (it's from ExtractTextPlugin) which allowed you to specify that behaviour we wouldn't need Md5HashPlugin.

@mjackson
Copy link
Contributor

AFAICT you're doing the exact same thing that I'm doing, Kent. Sticking the
manifest in the HTML. If you've got a plugin that makes it easier on you,
awesome 😄
On Fri, Jul 29, 2016 at 8:22 PM Jonny Buchanan notifications@github.com
wrote:

Should Md5HashPlugin be necessary if we have HashedModuleIdsPlugin?

HashedModuleIdsPlugin is to prevent module ids changing by not depending
on Webpack assigning integers in a particular order each time, without
having to store anythhing between builds.

Md5HashPlugin just happens to make [chunkhash](which changes if you're
extracting CSS from the same chunk) behave like [contenthash] - now I
think of it if there was default [contenthash] config (it's from
ExtractTextPlugin) which allowed you to specify that behaviour we
wouldn't need Md5HashPlugin.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#210 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAFqp8O4knmtmRJjJv3KHWBC-fqRBjAQks5qasN_gaJpZM4JVBvq
.

Michael Jackson
@mjackson

@okonet
Copy link

okonet commented Aug 24, 2016

BTW I wrote about my journey with long-term a long time ago and I've just updated it with mentions of MD5HashPlugin and https://github.com/szrenwei/inline-manifest-webpack-plugin

https://medium.com/@okonetchnikov/long-term-caching-of-static-assets-with-webpack-1ecb139adb95#.bbkwtwbvm

@gaearon
Copy link
Contributor Author

gaearon commented Feb 11, 2017

Let's revisit this (or alternatives) now that we're on WP2?

@gaearon
Copy link
Contributor Author

gaearon commented May 22, 2017

Let’s continue the discussion in #2328.

@lock lock bot locked and limited conversation to collaborators Jan 21, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants