Next.js: $RefreshReg$ is not defined in web worker after upgrading to 9.4.0

Created on 12 May 2020  路  6Comments  路  Source: vercel/next.js

Bug report

I believe this is a React Refresh-related issue.

Potentially relevant:

Describe the bug

After upgrading to Next.js 9.4.0, workers throw the following exception on load:

Uncaught ReferenceError: $RefreshReg$ is not defined
    at Module.eval (blocks.ts:239)
    at eval (blocks.ts:296)
    at Module../shared/blocks.ts (48ba4b417edc794a158b.worker.js:311)
    at __webpack_require__ (48ba4b417edc794a158b.worker.js:29)
    at Module.eval (WorldChunk.ts:12)
    at eval (WorldChunk.ts?c4f7:22)
    at Module../lib/Data/WorldChunk.ts (48ba4b417edc794a158b.worker.js:115)
    at __webpack_require__ (48ba4b417edc794a158b.worker.js:29)
    at Module.eval (WorldChunkReader.worker.ts?024a:1)
    at eval (WorldChunkReader.worker.ts?024a:21)

To Reproduce

  1. Configure worker-loader like so in next.config.js:
config.module.rules.unshift({
  test: /\.worker\.(js|ts|tsx)$/,
  loader: "worker-loader",
  options: {
    name: "static/[hash].worker.js",
    publicPath: "/_next/",
  },
});

// Overcome webpack referencing `window` in chunks
config.output.globalObject = "self";
  1. Load a worker
  2. See error

Expected behavior

No error, workers load successfully as in Next 9.3

Screenshots

image
image

System information

  • OS: macOS
  • Browser (if applies) Chrome
  • Version of Next.js: 9.4.0
  • Version of Node.js: 13.12.0
bug 3 p1

Most helpful comment

All 6 comments

In my case, I was able to work around this issue by ensuring that there is no direct overlap between:

  • Modules imported in React components
  • Modules imported in Worker bundles

@next/react-refresh-utils thought it was a React Refresh boundary, so it adds its metadata to the file. That metadata breaks workers since React isn't in the worker (though if you import * as React in the worker it still doesn't work). So you need to find a way to make it not think there are React Refresh boundaries in the workers.

This isn't a great fix because it meant moving functions to a bunch of individual files

I ran into this issue again and couldn鈥檛 use the previous workaround.

This time, I worked around it by renaming exported functions that are shared between React and Worker code to have a number in the function name 馃槄. This causes the heuristic for checking whether or not something is potentially a React component to return false (which is what React Refresh uses for refresh boundaries).

Can someone please provide a clonable complete reproduction so we can look into this?

I began seeing this same issue when I upgraded to next 9.4 from 9.3. It's only impacting dev for me, when I deployed it to vercel, the error was not there

I worked around this by manually disabling hasReactRefresh in the Webpack config in next.config.js:

module.exports = {
  webpack: (config) => {
    const nextBabelLoader = config.module.rules.find(
      (rule) => rule.use?.[1]?.loader === "next-babel-loader"
    );

    if (nextBabelLoader) {
      // Fix for https://github.com/vercel/next.js/issues/12753
      nextBabelLoader.use[1].options.hasReactRefresh = false;
    }

    return config;
  }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

pie6k picture pie6k  路  3Comments

timneutkens picture timneutkens  路  3Comments

renatorib picture renatorib  路  3Comments

knipferrc picture knipferrc  路  3Comments

ghost picture ghost  路  3Comments