Next.js: Worker is not defined, in NEXT JS 9+

Created on 9 Mar 2020  路  5Comments  路  Source: vercel/next.js

Bug report

Describe the bug

When trying to use web-workers using NEXT 9.1.1 and higher, the build is failing. Sometimes the dev build is throwing the error "Window is not defined" but after a couple of hmr refreshes, the worker seems to work. But the isse still persists when running prod build.

To Reproduce

  1. Install NEXT-JS 9 and then add simple web-worker.

I am sharing the sample git-repo where i am facing this issue and a code sandbox URL.

GitHub - https://github.com/JayaKrishnaNamburu/simple-next-workers
Codesandbox - https://codesandbox.io/s/happy-monad-cwr1t

Expected behavior

Prod build without breaking.

Screenshots

Screenshot 2020-03-09 at 8 39 17 PM

System information

  • OS: macOS Catalina
  • Browser: Observed in Chrome and Brave.
  • Version of Next.js: 9.1.1 and higher

Additional context

Most helpful comment

This is still an issue in 9.3.6. Is there an update on this?

All 5 comments

Install npm install worker-loader @zeit/next-workers and in next.config.js add the following:

module.exports = {
  webpack: (config) => {
    config.module.rules.push({
      test: /\.worker\.js$/,
      loader: 'worker-loader',
      options: {
        name: 'static/[hash].worker.js',
        publicPath: '/_next/'
      }
    })

    // Overcome Webpack referencing `window` in chunks
    config.output.globalObject = `(typeof self !== 'undefined' ? self : this)`

    return config
  }
}

This should fix the problem with referencing window in worker

One way to avoid this error is to wrap your worker imports inside a useEffect callback .

Here is how I got rid of the error using your code example:

import React, { useEffect, useState } from 'react';

const Home = () => {
  const [greetingMessage, setGreetingMessage] = useState('...');

  useEffect(() => {
    (async () => {
      const { greeting } = await import('../utils/utils');
      greeting().then(greetingMessage => {
        setGreetingMessage(greetingMessage);
      });
    })();
  }, []);

  return <h1>Hello {greetingMessage}</h1>;
};

export default Home;

However I strongly believe this is more of a workaround rather then and actual fix.
Also when using dynamic imports you lose tree shaking, so you got to be a bit more careful with your imports.

next 9.2.0 has the same problems.

This is still an issue in 9.3.6. Is there an update on this?

Closing as it started to work as expected in 9.4.4. Anyone looking for the implementation details --> https://github.com/teleporthq/teleport-repl/pull/58

Was this page helpful?
0 / 5 - 0 ratings