React-app-rewired: Build doesn't work properly

Created on 27 Nov 2019  路  13Comments  路  Source: timarney/react-app-rewired

My app works fine when I started trough the dev server but when I'm doing a build, inside the build folder there is no HTML or js file even though the build was completed without errors.
my config-overrides file:

module.exports = function override(config, env) {
    config.module.rules.push({
        test: /\.worker\.js$/,
        use: { loader: 'worker-loader' }
    });
    config.output.globalObject = 'this';
    return config;
};

All 13 comments

If you have a look at create-react-app's webpack configuration, you're not going to get what you're attempting properly.

You need to add your new rule into the config.modules.rules 'oneOf' rule array, and it _has_ to be before the last item currently in the list (otherwise the 'files' rule will be used instead of your own rule). You _also_ should modify the existing /\.(js|mjs|jsx|ts|tsx)$/ rule to add an exclusion so that it doesn't process your *.worker.js files (as currently both tests would match, so I think given how the files rule works that the first defined rule out of your worker one and the original javascript one will be used for those files).

Something like:

module.exports = function override(config, env) {
  // Find the oneOf rule
  const oneOfRuleIndex = config.module.rules.find((rule) => 'oneOf' in rule);
  if (oneOfRuleIndex < 0) {
    // Oops, test is wrong
    console.error("Did not find the oneOf rule!");
    // Exit here so that you can debug the failed test
    throw Error("oneOf Rule test failed");
  }
  const oneOfRule = config.module.rules[oneOfRuleIndex];

  // Find the rule for compiling the project's javascript
  const jsRuleIndex = oneOfRule.oneOf.find(
      (rule) => rule.test.toString() === "/\.(js|mjs|jsx|ts|tsx)$/"
  );
  if (jsRuleIndex < 0) {
    // Oops, test is wrong
    console.error("Did not find the standard javascript processing rule!");
    // Exit here so that you can debug the failed test
    throw Error("Rule test for /\.(js|mjs|jsx|ts|tsx)$/ failed");
  }

  // Add an exclusion to the normal javascript compile rule so that it doesn't try to compile
  // your worker files.
  const jsRule = oneOfRule.oneOf[jsRuleIndex];
  jsRule.exclude = /\.worker\.js$/;

  // Insert the new rule for your worker files into the oneOf rule array just before the normal javascript
  // compile rule
  oneOfRule.oneOf.splice(
    jsRuleIndex,
    0,
    {
      test: /\.worker\.js$/,
      use: { loader: 'worker-loader' }
    }
  );

  // Then do the rest of your overrides.
  config.output.globalObject = 'this';

  return config;
}

Note that I've put the above together off the top of my head, so there may be errors in the array.find functions for looking for the specific rules that need to be modified. You could also count the indexes for the various rules manually, but if they alter the order or add another loader those index numbers could change, whereas getting the indexes by testing for them is less likely to run into problems.

I cannot be sure without app code examples whether this _is_ the cause of not having the files in the build folder, but it definitely will be causing processing errors where the wrong rules are being applied/files being compiled with the wrong loaders, so it's a good place to start with fixing the build.

Based on @dawnmist response, but the problem remain the same.

module.exports = function override(config, env) {
  const oneOfRuleIndex = config.module.rules.findIndex((rule) => rule['oneOf'] !== undefined);
  if (oneOfRuleIndex < 0) {
    console.error("Did not find the oneOf rule!");
    // Exit here so that you can debug the failed test
    throw Error("oneOf Rule test failed");
  }

  const oneOfRule = config.module.rules[oneOfRuleIndex];

  // Find the rule for compiling the project's javascript
  const jsRuleIndex = oneOfRule.oneOf.findIndex(
    (rule) => rule.test && String(rule.test) === String(/\.(js|mjs|jsx|ts|tsx)$/)
  );
  if (jsRuleIndex < 0) {
    // Oops, test is wrong
    console.error("Did not find the standard javascript processing rule!");
    // Exit here so that you can debug the failed test
    throw Error("Rule test for /\.(js|mjs|jsx|ts|tsx)$/ failed");
  }
  // Add an exclusion to the normal javascript compile rule so that it doesn't try to compile
  // your worker files.
  const jsRule = oneOfRule.oneOf[jsRuleIndex];
  jsRule.exclude = /\.worker\.js$/;
  // Insert the new rule for your worker files into the oneOf rule array just before the normal javascript
  // compile rule
  oneOfRule.oneOf.splice(
    jsRuleIndex,
    0,
    {
      test: /\.worker\.js$/,
      use: { loader: 'worker-loader' }
    }
  );

  // Then do the rest of your overrides.
  config.output.globalObject = 'this';
  return config;
}

@timarney can you reopen this issue?

Please reopen I had to eject my react app in order to configure webpack with web workers properly. I'm 100% sure that there is something broken in react-app-rewired :(

Ok did some test, actually this happens when one of your .worker.js is not valid. Comment all unused/untested worker files and it should be ok.

In order to debug this any further, we will require an example repository that is affected by the issue.

Usually build issues like this turn out to be issues with the particular libraries that CRA's webpack configuration is using that also need their configuration to be adjusted in order to work together with what people are adding to the list through their config-overrides file. The only way in which react-app-rewired is actually involved is that it allowed the user to make changes to their build configuration that conflicted with those that were part of CRA's default build process. (I've used web-worker loaders with CRA 1.x and react-app-rewired 1.x, so I know from personal experience that it _used_ to work fine - it was for a personal project that I haven't had time or need to update any further).

Without a reproduceable example, there is no way to be able to step inside the particular combination of build libraries and configuration to find what is causing the issue.

As @espadon54 found, in their case the problem was actually due to one of their own source code files being invalid, which being as it was a worker file meant that it was only being included in the build when run with their config-overrides changes to include the webpack webworker loaders. @marcinburzynski - given that your file is compiling in an ejected repo that's likely not your issue - but if I'm understanding @espadon54's comment correctly it is now working for them with react-app-rewired once they fixed the worker file...which would indicate that it _can_ work with react-app-rewired.

If you can provide an example repository that has the issue, I'll take a look at the example over the next few days.

Yes exact @dawnmist, it's working fine now, it was just because of invalid .worker.js files.

Hi!

I'm having the same issue here. I've already check for unused workers and everything looks fine.

curve.worker.js

import { anotherCurvePoints } from "../utils/reports/sCurve"

self.addEventListener('message', event => {
    const {
        masterPlanToUse,
        blTasks,
        blOrder
    } = event.data
    const sCurve = {}

    sCurve.masterPlan = anotherCurvePoints(masterPlanToUse, undefined, blOrder)
    sCurve.baseline = anotherCurvePoints(masterPlanToUse, blTasks, blOrder)


    self.postMessage(sCurve)
})

My "config-overrides" is like the one was coded by @dawnmist

If you need more info, please let me know.

@aibarr Can you provide an example repository that has the issue that I can run to debug? I can't do anything with just a few file fragments.

Thanks for the response @dawnmist
I've created a repo with a very simple example. As you can test, it can run on development, but when you try to build the repo it compiles nothing with no warinings

worker-exam

Sorry for maintain active this thread.

I've come with a workaround. Looks like that "self" on workers stops the production build, while this is not event warned by the develop build. I've added "// eslint-disable-next-line" before any "self" statement and it working fine.

import JustDoing from '../utils'

// eslint-disable-next-line
self.addEventListener('message', function (event) {
    JustDoing(event.data)

    // eslint-disable-next-line
    self.postMessage(event.data)
})

Thank you @aibarr - you have found the cause for the repo you shared before I got a chance to look at it. :)

Create-react-app has the "no-restricted-globals" rule for eslint active and set to "error" - see https://github.com/facebook/create-react-app/blob/f875bb0c8444720f5eac1b24822e10421b9f1202/packages/eslint-config-react-app/index.js#L189 and "self" is in the list of restricted globals - see https://github.com/facebook/create-react-app/blob/f875bb0c8444720f5eac1b24822e10421b9f1202/packages/confusing-browser-globals/index.js#L63

This means that when the file is linted as part of the production build, it fails the eslint checks.

You can test this separately from the build by creating a script in your package.json file:

scripts: {
  lint: eslint --config node_modules/eslint-config-react-app/index.js ./src
}

If you get any errors reported from running yarn lint or npm run lint after creating that script, your production build is guaranteed to fail due to the eslint errors.

Turning off eslint rules can either be done for an individual line, or for a particular rule for a whole file if desired. See the eslint documentation on disabling rules with inline comments for several methods for working around eslint rule issues for rules that create-react-app enables.

Alternatively, refer to the create-react-app documentation on setting up your editor for viewing eslint errors in the editor, and particularly to the section on extending the eslint config if you want to alter/customize the eslint rules being run (e.g. so that 'self' is no longer treated as a restricted global - if you imported the same globals list that create-react-app uses then filtered the 'self' item out of it, you could then keep the rest of the restricted globals active without having to disable the rule entirely).

This is once again not a bug within react-app-rewired that caused the issue, and a very good example for why it is important to provide an example repository for debugging odd issues like this one. The issue was due to the _specific combination of code and configuration_ used for the project rather than due to any bug in _any_ of the related libraries or user's project code.

Thanks for the discussion, it helped me find my issue. However, I'd like to politely disagree with this statement:

This is once again not a bug within react-app-rewired that caused the issue...

During build, I see this output:

Creating an optimized production build...
Compiled successfully.

..... while it should say "build cancelled due to lint errors" or similar. Maybe you don't want to call this a bug for some reason, but at the very least it's highly inconvenient.

For comparison, if I run a build with react-scripts and a similar lint problem is encountered, the build output includes this (while the build runs successfully):

./src/App.js
  Line 5:5:  'x' is assigned a value but never used  no-unused-vars

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

@oliversturm That message is coming from react-scripts itself, not react-app-rewired: https://github.com/facebook/create-react-app/blob/4582491a8b46be6c98c0934df1fb7ae81c95f6c1/packages/react-scripts/scripts/build.js#L85-L99

The problem is that worker files are a separate compilation/separate target to the main build, and since they're not supported by react-scripts itself I don't think react-scripts is checking the build warnings for them. As such, as far as react-scripts can see there were no warnings in the main build, so it reports success instead.

Again, this is not _caused_ by any code in react-app-rewired. If you wanted to place "blame" somewhere, I'd suggest looking into Webpack's failure to notify react-scripts of any build warnings for worker files.

Was this page helpful?
0 / 5 - 0 ratings