Webpack and Jest v0.36 Upgrade Guide

Redwood v0.36 includes significant major version upgrades for both Webpack and Jest, which means snappier performance and overall stability improvements. Storybook is also now using Webpack v5. The majority of projects should not experience upgrade issues. If your project includes custom implementation, refer to the following Docs for help upgrading.

Please use this Forum post for help and discussion regarding any problems or questions you have.

Webpack v5

Webpack v5 itself has a comprehensive upgrade guide, which you can view here:

Note: “If you have rules defined for loading assets using raw-loader, url-loader, or file-loader, please use Asset Modules instead as they’re going to be deprecated in near future.”: Asset Modules | webpack

Webpack-Dev-Server v4

Dev Server, which supports Webpack v5, is a separate package that has it’s own breaking changes and migration guide:

Also see:

Jest v27

Although there’s a lot of changes overall in v27, the major change that may affect custom implementations is the test runner change from Jasmine2 to Jest-Circus. Additionally, Jest now uses Node as the default test envirmonment (instead of JSDOM); however, this update was handled internally within the @redwoodjs/testing package and should be a seamless transition for most projects.

For Release Notes and breaking changes:

Additional resources:

Note: Jest test() no longer allows done callback and a Promise:

Hi @thedavid I upgraded to v0.36 and all was good until I added Twilio. Now I’m getting quite a lot of webpack errors. I don’t have any custom Webpack configuration and so wondering if these are expected or if I might have missed a step when upgrading from v0.35? (apologies if that’s the case)

FYI, I have come across the following

And these are the errors I’m getting

Compiled with problems:

Error:
Module not found: Error: Can't resolve 'net' in '/Users/bob/dev/redwood/redwood_project/node_modules/https-proxy-agent/dist'

Error:
Module not found: Error: Can't resolve 'tls' in '/Users/bob/dev/redwood/redwood_project/node_modules/https-proxy-agent/dist'

Error:
Module not found: Error: Can't resolve 'crypto' in '/Users/bob/dev/redwood/redwood_project/node_modules/jwa'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }

Error:
Module not found: Error: Can't resolve 'stream' in '/Users/bob/dev/redwood/redwood_project/node_modules/jws/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
	- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "stream": false }

Error:
Module not found: Error: Can't resolve 'stream' in '/Users/bob/dev/redwood/redwood_project/node_modules/jws/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
	- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "stream": false }

Error:
Module not found: Error: Can't resolve 'stream' in '/Users/bob/dev/redwood/redwood_project/node_modules/jws/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
	- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "stream": false }

Error:
Module not found: Error: Can't resolve 'crypto' in '/Users/bob/dev/redwood/redwood_project/node_modules/scmp'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }

Error:
Module not found: Error: Can't resolve 'fs' in '/Users/bob/dev/redwood/redwood_project/node_modules/twilio/lib/base'

Error:
Module not found: Error: Can't resolve 'os' in '/Users/bob/dev/redwood/redwood_project/node_modules/twilio/lib/rest'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "os": require.resolve("os-browserify/browser") }'
	- install 'os-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "os": false }

Error:
Module not found: Error: Can't resolve 'crypto' in '/Users/bob/dev/redwood/redwood_project/node_modules/twilio/lib/webhooks'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }

Error:
Module not found: Error: Can't resolve 'net' in '/Users/bob/dev/redwood/redwood_project/node_modules/https-proxy-agent/dist'

Error:
Module not found: Error: Can't resolve 'tls' in '/Users/bob/dev/redwood/redwood_project/node_modules/https-proxy-agent/dist'

Error:
Module not found: Error: Can't resolve 'crypto' in '/Users/bob/dev/redwood/redwood_project/node_modules/jwa'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }

Error:
Module not found: Error: Can't resolve 'stream' in '/Users/bob/dev/redwood/redwood_project/node_modules/jws/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
	- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "stream": false }

Error:
Module not found: Error: Can't resolve 'stream' in '/Users/bob/dev/redwood/redwood_project/node_modules/jws/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
	- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "stream": false }

Error:
Module not found: Error: Can't resolve 'stream' in '/Users/bob/dev/redwood/redwood_project/node_modules/jws/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
	- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "stream": false }

Error:
Module not found: Error: Can't resolve 'crypto' in '/Users/bob/dev/redwood/redwood_project/node_modules/scmp'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }

Error:
Module not found: Error: Can't resolve 'fs' in '/Users/bob/dev/redwood/redwood_project/node_modules/twilio/lib/base'

Error:
Module not found: Error: Can't resolve 'os' in '/Users/bob/dev/redwood/redwood_project/node_modules/twilio/lib/rest'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "os": require.resolve("os-browserify/browser") }'
	- install 'os-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "os": false }

Error:
Module not found: Error: Can't resolve 'crypto' in '/Users/bob/dev/redwood/redwood_project/node_modules/twilio/lib/webhooks'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }

Great question/catch and sorry I missed this obvious big change in my original post!

Buried in the Webpack v5 migration guide is a bullet-point about:

  • webpack 5 no longer includes a polyfill for this Node.js variable. Avoid using it in the frontend code.

By no longer including these Node polyfills, Webpack v5 dropped a lot of overhead. But now we have to specify 1) if they are needed and/or 2) a fallback if so.

We ran into this issue specifically for our Storybook + Webpack config. The error flagged several modules; however, we did not need to include the polyfill so we could just use the {" moduleName ": false} option. Take a look at how we implemented the config via this commit:

Next Steps

  1. If your project doesn’t include custom Webpack config already, then run yarn rw setup webpack
  2. within web/config/webpack.config.js basically follow the instructions from the weback console error output for each module it identifies: tls, crypto, stream, etc
  3. you can likely start by trying “false” for each of them, e.g. resolve.fallback: { "crypto": false }. If that breaks (or Twilio breaks), then try the option to add the polyfill, e.g. resolve.fallback: { "crypto": require.resolve("crypto-browserify") } (note: you’ll need to install crypto-browserfy)

So you’re webpack.config.js might look like:

module.exports = (config, { mode }) => {
  if (mode === 'development') {
    // Add dev plugin
  }
  config.resolve.fallback = {
    fs: false,
    tls: false,
    net: false,
    stream: false,
    crypto: require.resolve('crypto-browserify'), // don't forget to install!
  }

  return config
}

Let me know how it goes!

2 Likes

Thank you @thedavid :raised_hands:
V much appreciate your detailed response. The following config works :slight_smile:

//webpack.config.js

/** @returns {import('webpack').Configuration} Webpack Configuration */
module.exports = (config, { mode }) => {
  if (mode === 'development') {
    // Add dev plugin
  }

  config.resolve.fallback = {
    fs: false,
    tls: false,
    net: false,
    stream: false,
    crypto: false,
    os: false,
  }

  // Add custom rules for your project
  // config.module.rules.push(YOUR_RULE)

  // Add custom plugins for your project
  // config.plugins.push(YOUR_PLUGIN)

  return config
}
3 Likes

Fantastic! Thank you for updating here. You just saved a lot of people a lot of time :rocket:

3 Likes

Thanks for this!

With a project set up with Typescript, when I include a webpack config file with fallbacks, the build is successful but in localhost:8910 there is an error in the console The superclass is not a constructor

For reference, I am trying to get Sending Emails | RedwoodJS Docs working with a Typescript project.

/** @returns {import('webpack').Configuration} Webpack Configuration */
module.exports = (config, { mode }) => {
  if (mode === 'development') {
    // Add dev plugin
  }

  config.resolve.fallback = {
    child_process: false,
    crypto: false,
    dns: false,
    fs: false,
    http: false,
    https: false,
    net: false,
    os: false,
    path: false,
    stream: false,
    tls: false,
    zlib: false,
  }

  // Add custom rules for your project
  // config.module.rules.push(YOUR_RULE)

  // Add custom plugins for your project
  // config.plugins.push(YOUR_PLUGIN)

  return config
}