I'm developing an application created using create-react-app

But then I needed to use mediainfojs library, this library requires wasm files, and based on what I understood I couldn't add it using create-react-app, I had to eject it.

After ejecting it, I went to mediainfo information on how to add the wasm on the webpack

They use the CopyPlugin, but then when I tried to do that it complained about the versions of my webpack (4) and the CopyPlugin.... so, I decided to migrate to webpack 5

That is when the pain starts... after follow their migration tutorial and do a bunch of modifications on my webpack.config I got to the following error while runing yarn build:

Module not found: Error: You attempted to import /MyWorkspace/project/node_modules/babel-preset-react-app/node_modules/@babel/runtime/helpers/esm/asyncToGenerator which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.

The only place calling this babel-preset-react-app are in the configuation

Here:

                {
                    test: /\.(js|mjs|jsx|ts|tsx)$/,
                    include: paths.appSrc,
                    loader: require.resolve("babel-loader"),
                    options: {
                        customize: require.resolve(
                            "babel-preset-react-app/webpack-overrides"
                        ),

And here:

                {
                    test: /\.(js|mjs)$/,
                    exclude: /@babel(?:\/|\\{1,2})runtime/,
                    loader: require.resolve("babel-loader"),
                    options: {
                        babelrc: false,
                        configFile: false,
                        compact: false,
                        presets: [
                            [
                                require.resolve("babel-preset-react-app/dependencies"),
                                { helpers: true },
                            ],
                        ],
                        cacheDirectory: true,
                        cacheCompression: isEnvProduction,

                        // If an error happens in a package, it's possible to be
                        // because it was compiled. Thus, we don't want the browser
                        // debugger to show the original code. Instead, the code
                        // being evaluated would be much more helpful.
                        sourceMaps: false,
                    },
                },

I have looked into similar issues reported here, but mostly of them seem to be related to either static files being dynamically imported or imports referencing ".." dir after the project directory

The full webpack config file is here

I'm probably missing something very silly, I'd be glad if someone can point it out.

4

There are 4 answers

0
Ben Callaway On BEST ANSWER

I'm also attempting to upgrade an ejected CRA project to Webpack 5. I was able to move forward using babel-preset-react-app-webpack-5, only to encounter the next CRA-related issue.

Be sure to replace calls like require.resolve("babel-preset-react-app/dependencies") with require.resolve("babel-preset-react-app-webpack-5/dependencies").

Also, be aware the package does not appear to be production-ready, but my own project is still in early development.

0
ptkvsk On

Solution 1: You can resolve this by putting every single error path inside the ModuleScopePlugin constructor inside the resolve.plugins section of webpack.config.js, like this:

new ModuleScopePlugin(paths.appSrc, [
    '/MyWorkspace/project/node_modules/babel-preset-react-app/node_modules/@babel/runtime/helpers/esm/asyncToGenerator'
]

NOTE: you must put the exact paths from the error messages (no trailing .js if it wasn't in the error message). The problem with this solution is that you'll have to put a dozen of such paths for your build to succeed...

Solution 2 (better?): Go to your package.json and add "absoluteRuntime": false here:

"babel": {
    "presets": [
      [
        "react-app",
        {
          "absoluteRuntime": false
        }
      ]
    ]
  }

NOTE: double square brackets are not a mistake. It won't work with single square brackets.

WARNING: I don't understand the consequences of this solution; use your own judgement. It kind of seems that false is the default in @babel/preset-react (see here), so I'm not sure why it has to be explicitly set to false for babel-preset-react-app (which is a facade for @babel/preset-react if I'm not mistaken?).

0
Josh Reep On

I had this issue with a few other babel packages after trying to upgrade an ejected CRA app to webpack v5. I tried many different approaches some of which worked in dev but not in prod and vice versa. I found this comment in the storybook github and it was the only thing that that seemed to work in all scenarios for me.

It's kinda annoying, but by simply moving the offending packages from devDependencies in my package.json to dependencies, it seems to fix the issue. I could spend more time trying to figure out why that fixes it, but I'll leave that to someone with more free time. :)

2
Elinor On

I had a similar challenge and I was able to fix this by adding these definitions at the top of my webpack.config file

const babelRuntimeEntry = require.resolve('babel-preset-react-app');
const babelRuntimeEntryHelpers = require.resolve(
 '@babel/runtime/helpers/esm/assertThisInitialized',
  { paths: [babelRuntimeEntry] }
);
const babelRuntimeRegenerator = require.resolve('@babel/runtime/regenerator', {
  paths: [babelRuntimeEntry]
});

Then where you have the ModuleScopePlugin in the resolve.plugins update it to be

new ModuleScopePlugin(paths.appSrc, [
      paths.appPackageJson,
      babelRuntimeEntry,
      babelRuntimeEntryHelpers,
      babelRuntimeRegenerator])