Explore support for async/dynamic chunk names (POC) by addyosmani · Pull Request #9 · numical/script-ext-html-webpack-plugin

This plugin does a great job of preloading and prefetching resources already defined as part of your static HTML 👍 Where it doesn't quite work as well is for script chunks generated on-the-fly by Webpack as part of code-splitting. Let's say I generate a few chunks that I want to lazy-load later on in my user-journey and so I'd like to preload or prefetch them in the current view to warm up the cache.

These chunks do not have names known ahead of time can often have a build-time generated hashname, such as chunk.31132ae6680e598f8879.js.Due to the way the plugin is currently setup, it requires assets specified in the preload or prefetch arrays to match HTML tags. This means, even if you wanted to supply an array of build-time generated chunk names to the plugin, it wouldn't really work (from what I can tell) unless you first inject them into your HTML via a separate html-webpack-plugin add-on.

Ideally, there would be a clean way to say you want to preload or prefetch dynamically generated chunks and have script-ext-html-webpack-plugin handle that for you. @numical would you be up for discussing support for that, or is that a use-case this plugin doesn't really want to target?

To see how feasible this might be, I put together a POC that effectively does the following:

In your script-ext-html-webpack-config, you can now define the following field:

dynamicChunks: { 
  preload: true
}

In this simplest of forms, it will inject into the <head> any dynamic chunks extracted from the compilation step as link rel=preload elements with type as=script. To customize it to inject such chunks into the <body>, one can do:

dynamicChunks: {
  preload: true,
  position: 'body'
}

The above will also work for prefetch. For a quick demo of the output, here's a sample config running against a project where two dynamic chunks are generated. I'm specifying the defaultAttribute just to show that things should still work fine with the rest of the plugin.

  new ScriptExtHtmlWebpackPlugin({
    dynamicChunks: {
      preload: true,
      position: 'head'
    },
    defaultAttribute: 'defer'
  })

And the output:

<html>
  <head>
    <title>...</title>
  <link rel="preload" href="chunk.31132ae6680e598f8879.js" as="script"></link>
  <link rel="preload" href="chunk.d15e7fdfc91b34bb78c4.js" as="script"></link>
</head>
  <body>
    <div id="root"></div>
  <script type="text/javascript" src="/vendor.bundle.js" defer></script>
  <script type="text/javascript" src="/bundle.js" defer></script>
</body>
</html>

The current PR isn't meant to be a proposal for a final API to intro support for this feature, but it's just something to get the discussion started. I'm curious if there might be interest in supporting something like this. Happy to keep working on it or hand-off work on it if there's a better way of supporting the use-case.

Thanks! 💘