Skip to content

HMR not working with multiple entries #2792

Closed

Description

@slightlyfaulty
  • Operating System: Linux
  • Node Version: 14.14.0
  • NPM Version: 6.14.7
  • webpack Version: 5.2.0
  • webpack-dev-server Version: 3.11.0
  • Browser: Google Chrome
  • This is a bug
  • This is a modification request

Code

https://github.com/slightlyfaulty/webpack-hmr-multi-entry-repro

// webpack.config.js
...
entry: {
  first: ['./src/first.js', './src/first.css'],
  second: ['./src/second.js', './src/second.css'],
},
...

Expected Behavior

After starting the dev server, hot module replacement should work for all JS and CSS files from all webpack entries.

Actual Behavior

Hot module replacement doesn't work for all entries. Only files from the second entry are hot reloaded when changed. Files from the first entry do not get hot reloaded when changed.

For Bugs; How can we reproduce the behavior?

  1. Clone repro then yarn && yarn start
  2. Open http://localhost:8080/
  3. Change src/first.js and src/first.css - notice they are not hot reloaded
  4. Change src/second.js and src/second.css - notice they are hot reloaded

Activity

  1. slightlyfaulty commented on Oct 22, 2020

    @slightlyfaulty
    Author

    Upon further testing, it seems that HMR only works for the last loaded JS bundle on the page. HMR will not work for any JS bundle loaded before it. The order of the entries in webpack.config.js does not matter.

  2. MohsenElgendy commented on Nov 9, 2020

    @MohsenElgendy

    @slightlyfaulty setting optimization.runtimeChunk: "single" fixed the problem for me.

  3. slightlyfaulty commented on Nov 9, 2020

    @slightlyfaulty
    Author

    Thanks for the tip @MohsenElgendy, but it's still not really ideal as you need to then load the runtime chunk alongside your other bundles. Webpack 4 handled embedding the runtime in multiple bundles at the same time no problem.

  4. waldronmatt commented on Nov 11, 2020

    @waldronmatt

    I can also confirm optimization.runtimeChunk: "single" fixed the problem for me handling multiple bundles.

    webpack.dev.config

    module.exports = () => {
      const config = {
        mode: 'development',
        // Map your compiled code back to your original source code.
        devtool: 'inline-source-map',
        target: 'web',
        output: {
          filename: '[name].js',
          // specify chunck path for code splitted files
          chunkFilename: '[name].js',
        },
        devServer: {
          historyApiFallback: true,
          contentBase: path.resolve(__dirname, '../dist'),
          publicPath: '/',
          open: true,
          compress: true,
          hot: true,
          port: 8080,
        },
        plugins: [
          new ESLintPlugin({
            extensions: ['js', 'ts'],
          }),
          new StylelintPlugin(),
          new webpack.HotModuleReplacementPlugin(),
        ],
        optimization: {
          // don't minimize so we can debug
          minimize: false,
          /*
            The value 'single' instead creates a runtime file to be shared for all generated chunks.
            https://github.com/webpack/webpack-dev-server/issues/2792
          */
          runtimeChunk: "single",
        },
      };
      return merge(common('development'), config);
    };
    

    webpack.common.js

    module.exports = (env) => {
      const isProduction = env === 'production';
    
      ...
    
      return {
        target: 'web',
        entry: {
          main: [
            './src/js/index.js',
            './src/ts/index.ts',
          ],
          // webpack code splitting example file
          examples: [
            './src/js/examples.js',
          ],
        },
        output: {
          path: path.join(__dirname, '../dist'),
          publicPath: '/',
        },
    
      ...
    
    };
    
  5. uxsoft commented on Nov 20, 2020

    @uxsoft

    Same issue here, setting optimization.runtimeChunk: "single" fixed the problem for me as well, but I would consider this a workaround for a bug that should be fixed anyway. This certainly worked before.

  6. alexander-akait commented on Nov 20, 2020

    @alexander-akait
    Member

    I think it fixed in v4 branch, you can try it

  7. slightlyfaulty commented on Nov 25, 2020

    @slightlyfaulty
    Author

    @evilebottnawi Can't test properly because it seems writeToDisk has been removed in v4 for some reason?

    Initial compilation also takes much longer than the regular build time now. Over 6 seconds compared to <2 seconds for regular build. On v3 it only takes about 2.2 seconds for the initial dev server compilation.

  8. alexander-akait commented on Nov 25, 2020

    @alexander-akait
    Member

    It was not removed, it was moved to dev: { writeToDisk: true }

  9. alexander-akait commented on Nov 25, 2020

    @alexander-akait
    Member

    There is no changes between v3 and v4 in perf

  10. slightlyfaulty commented on Nov 25, 2020

    @slightlyfaulty
    Author

    It was not removed, it was moved to dev: { writeToDisk: true }

    Aha.. that's working now, but can confirm this bug is still present. Only the last loaded bundle in the document hot reloads properly. Bundles from other entries do not hot reload at all.

    Also had to explicitly disable liveReload, otherwise it live reloaded the page after every change, even though hot is enabled.

    There is no changes between v3 and v4 in perf

    Evidence would suggest otherwise sir. Will open an issue after release of v4 if it persists.

  11. alexander-akait commented on Nov 26, 2020

    @alexander-akait
    Member

    @slightlyfaulty Please create reproducible test repo, it should work

  12. slightlyfaulty commented on Nov 26, 2020

    @slightlyfaulty
    Author

    @alexander-akait Sure. https://github.com/slightlyfaulty/webpack-hmr-multi-entry-repro

    1. yarn && yarn start - Open http://localhost:8080/
    2. Change src/first.js and src/first.css - notice they are not hot reloaded, and there are some errors in the browser console
    3. Change src/third.js and src/third.css - notice they are hot reloaded correctly, because they're loaded last in the page
  13. onetrev commented on Dec 6, 2020

    @onetrev

    Is there a reason to avoid multiple entry points / bundles, because I'm surprised that not a ton of people are also reporting this bug? I know I need to have them. One example is I need certain things loaded in my site header and the rest at the end of the body.

    One thing to note / add to the error report from @slightlyfaulty, I noticed all the console messages come in as warnings not errors, even though indeed HMR spews out a tons of warning messages like so:

    [HMR] Update failed: Loading hot update chunk site_header failed.
    (missing: https://localhost:3018/dist/site_header.3fb54bab211f3a92bb04.hot-update.js)
    loadUpdateChunk/<@https://localhost:3018/dist/site_header.bundle.js:10391:26
    
  14. 38 remaining items

  15. slightlyfaulty commented on Mar 4, 2022

    @slightlyfaulty
    Author

    @khelkun I recently discovered that if you use the dependOn option for an entry, then it will use the runtime that's embedded in the entry it depends on.

    In this case you don't need to use runtimeChunk: 'single' anymore, as long as the dependOn entry is always loaded first.

  16. shalkauskas commented on Jun 13, 2022

    @shalkauskas

    @slightlyfaulty thank you, worked great with webpack 5!

  17. bradyclifford commented on Jun 25, 2022

    @bradyclifford

    @slightlyfaulty you wouldn't happen to have an example you could share with the dependOn working for you?

  18. slightlyfaulty commented on Jun 25, 2022

    @slightlyfaulty
    Author

    @bradyclifford I've pretty much just got my entry points listed like the examples in the docs. Nothing special.

    https://webpack.js.org/concepts/entry-points/#entrydescription-object

  19. thebat93 commented on Aug 10, 2022

    @thebat93

    I'm having a problem with HMR when Webpack has multiple entries and one of them is a service worker.

    If I use runtimeChunk: 'single' hot reloading works as intended. But none of service worker's hooks runs.

    I found this solution. With this service worker's hooks run, but this breaks hot reloading. When I try to update the app code I get warnings and nothing gets updated:
    [HMR] Update failed: ReferenceError: document is not defined
    [HMR] Update failed: ChunkLoadError: Loading hot update chunk runtime-app failed.

    Has anyone faced this problem? I'm using Webpack 5 with the following options:

    entry: {
      app: ['/index.tsx'],
      'service-worker': '/service-worker.js',
    },
    output: {
      filename: pathData => {
        if (pathData?.chunk?.name === 'service-worker') {
          return '[name].js';
        }
        return '[name].[contenthash].bundle.js';
      },
    },
    optimization: {
        runtimeChunk: {
          name: (entrypoint) => {
            if (entrypoint.name.startsWith("service-worker")) {
              return null;
            }
            return `runtime-${entrypoint.name}`;
          },
        },
        splitChunks: {
          chunks(chunk) {
            return chunk.name !== "service-worker";
          },
          cacheGroups: {
            default: false,
            vendors: false,
            framework: {},
            lib: {},
            commons: {},
            shared: {},
            styles: {}
          },
          maxInitialRequests: 25,
          minSize: 20000
        },
    },
    
  20. thebat93 commented on Aug 15, 2022

    @thebat93

    Here is a minimal test repo with the issue: https://github.com/thebat93/sw-webpack-hmr
    I mentioned solutions that I tried in webpack config file.

  21. develobora commented on Dec 9, 2022

    @develobora

    Not working for me also with multiple entries. "webpack": "^5.53.0", "webpack-dev-server": "^4.7.4".

  22. alexcloudstar commented on Jul 11, 2023

    @alexcloudstar

    @slightlyfaulty Found solution:

    <script type="text/javascript" src="dist/runtime.js"></script>
    <script type="text/javascript" src="dist/first.js"></script>
    <script type="text/javascript" src="dist/second.js"></script>
    <script type="text/javascript" src="dist/third.js"></script>
    
    optimization: {
      runtimeChunk: 'single'
    },
    

    Thank you! is working perfectly fine.

    Here is a part of my package.json (i'm doing micro-frontends btw I don't know if is matter or not because I do have the same packages installed)

    "scripts": {
        "start": "webpack serve --config config/webpack.dev.js",
        "build": "webpack --config config/webpack.prod.js"
      },
    

    devDeps:

    "babel-loader": "^9.1.3",
    "webpack": "^5.88.1",
    "webpack-cli": "^5.1.4",
    "webpack-dev-server": "^4.15.1",
    "webpack-merge": "^5.9.0"
    "babel-loader": "^9.1.3",
    "html-webpack-plugin": "^5.5.3",
    "typescript": "^5.1.6",
    "@babel/core": "^7.22.8",
    "@babel/plugin-transform-runtime": "^7.22.7",
    "@babel/preset-env": "^7.22.7",
    "@babel/preset-react": "^7.22.5",
    
  23. slightlyfaulty commented on Jul 11, 2023

    @slightlyfaulty
    Author

    Closing this. In Webpack 5 optimization.runtimeChunk: "single" and/or dependOn/runtime should be used appropriately to control where the runtime is embedded. Otherwise each entry contains a runtime resulting in this issue.

  24. added a commit that references this issue on Nov 21, 2023
  25. added a commit that references this issue on Nov 21, 2023
  26. added a commit that references this issue on Nov 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions