timarney / react-app-rewired

Override create-react-app webpack configs without ejecting
MIT License
9.79k stars 425 forks source link

Support CRA 4 #516

Closed oleksii-boiko closed 2 years ago

shovon commented 3 years ago

I just tried.

CRA 4.0 works perfectly fine.

shovon commented 3 years ago

Went to sleep, to see if I'm not crazy. I'm now woken up, fully alert, and ready to focus.

TL;DR: it still works on CRA 4.0, for precisely the reason that I intend to use react-app-rewired for.

So I just created a new CRA 4.0 app in a monorepo that I'm working on. react-scripts is indeed version 4.0.1 in the package.json.

Just installed react-app-rewired, updated the scripts field in the package.json, and created a config-overrides.js file. That file has the following code:

module.exports = function override(config, env) {
  throw new Error("Not really an error");
  return config;
};

Note: I intentionally throw a runtime exception in the override, just to see if the configs are indeed overridden.

Then I invoke yarn start, and this is the console output:

$ react-app-rewired start
Not really an error
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Also, the dev server does not start.

This indicates to me that config-overrides.js is indeed being picked up.

So, I remove the runtime exception, and the dev server starts up just fine.

My primary motivation for using react-app-rewired is so that I can import components from a Storybook package in the monorepo that I'm working on. Without react-app-rewired, I just can't do that, especially if the particular component uses Font Awesome (for some reason that I cannot explain).

So, I go ahead, and import the module without adding anything new to config-overrides.js, and sure enough, it doesn't work.

Then, I change the config-overrides.js to the following:

const {
  removeModuleScopePlugin,
  override,
  babelInclude,
} = require("customize-cra");
const fs = require("fs");
const path = require("path");

const projects = fs
  .readdirSync(path.resolve(".."))
  .map((name) => path.resolve(`../${name}/src`));

module.exports = override(
  removeModuleScopePlugin(),
  babelInclude([path.resolve("src"), ...projects])
);

And it works.

It even works with Fast Refresh (a new feature in CRA 4.0), so I get hot module reloading, without having to resort to installing a third-party module.

trongthanh commented 3 years ago

@shovon Have you tried react-app-rewired build and then static serve the build folder? For me, the build succeeded but I received this error: Uncaught ReferenceError: exports is not defined in browser console.

shovon commented 3 years ago

@shovon Have you tried react-app-rewired build and then static serve the build folder? For me, the build succeeded but I received this error: Uncaught ReferenceError: exports is not defined in browser console.

@trongthanh Yes I have, and it works perfectly fine.

But to be fair, I tried it on a small project, and I don't know what the result would be like on a far more elaborate project.

shovon commented 3 years ago

@trongthanh I just tried it on a fresh project, outside of my monorepo, hopefully not polluted by whatever other peer-dependencies there are in the monorepo, and I can confirm, that replacing react-scripts with react-app-rewired still yields a perfectly valid build.

I'm interested to see what your code looks like.

trongthanh commented 3 years ago

@shovon I tried to reproduce my issues on a separate minimal setup (so that I can share it here) with 2 requirements from my commercial project: linaria and babel-plugin-module-resolver. Since I configure the demo from scratch, I tried out customize-cra this time and interestingly, both react-app-rewired start and react-app-rewired build && serve build work fine now.

I'm reworking these working configs back to the commercial project and see if they really resolve my issues.

shovon commented 3 years ago

I could almost swear that the last time that I visited this thread, there were only 8 🎉 reactions, but now there are 9.

This could indicate to me that CRA 4.0 may still be an issue.

Either that, or people just haven't actually tried CRA 4.0 with react-app-rewired.

jibin2706 commented 3 years ago

Upgrade worked without any major issue.

shovon commented 3 years ago

OK, now a 10th person has reacted with 🎉.

Why?

Does it not work?

helloncanella commented 3 years ago

HMR doesn't work.

The changes I've done on the code requires the reload of the page to be visible.

shovon commented 3 years ago

HMR doesn't work.

The changes I've done on the code requires the reload of the page to be visible.

@helloncanella Just tried it with react-scripts 4.0.2.

It still works.

https://user-images.githubusercontent.com/284576/106832008-c5120080-6645-11eb-8a89-a87208a86fbe.mov

good-idea commented 3 years ago

Ok, I found something interesting - my issue is babel-related and has something to do with my yarn.lock file. Here's how it happened:

  1. I was using react-scripts@3.x, nothing re-wired.
  2. I upgraded to react-scripts@4.0.1 - there were some internal changes in that package related to css-loader that broke my current setup.
  3. I installed react-app-rewired, updated my config with config-overrides.js
  4. Everything worked! Merged to main.
  5. A colleague branched off of main with the new CRA4+rewired setup. He installed some unrelated dependencies, and then our builds started failing.
  6. I check out to the commit on main and try react-app-rewired build, it still worked.
yarn run v1.22.5
$ react-app-rewired build
Creating an optimized production build...
Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`
Compiled successfully.
  1. I remove yarn.lock and then reinstall. NOW the build fails:
yarn run v1.22.5
$ react-app-rewired build
The following changes are being made to your tsconfig.json file:
  - compilerOptions.jsx must be react-jsx (to support the new JSX transform in React 17)

Creating an optimized production build...
Failed to compile.

/Users/joseph/Sites/sanctuary/tablet/src/components/Ad.tsx
TypeScript error in /Users/joseph/Sites/sanctuary/tablet/src/components/Ad.tsx(1,8):
'React' is declared but its value is never read.  TS6133

  > 1 | import React, { Component } from 'react';
      |        ^
    2 | import cx from 'classnames';
    3 | import AdSense from 'react-adsense';
    4 |

error Command failed with exit code 1.

It looks like there was some residual stuff in yarn.lock from earlier installs that was barely holding it together - but a fresh install breaks.

erlioniel commented 3 years ago

@good-idea It will be great to see a diff between yarn.lock-s for your case. Otherwise it's quite hard to understand what's wrong in your case. And, just for the record, it might be not related to rewire at all.

good-idea commented 3 years ago

@erlioniel thanks for your comment. We've moved back to using vanilla CRA for now - so this isn't an issue on our end anymore.

Arkellys commented 3 years ago

HMR doesn't work.

The changes I've done on the code requires the reload of the page to be visible.

@helloncanella I had a problem with HMR not working properly too but it comes from the new fast refresh feature of CRA 4. Take a look at this issue.

mihanizm56 commented 3 years ago

Have the same error - HMR not work - only if I set in .env FAST_REFRESH=false But I want to have HMR in my projects....

"customize-cra": "1.0.0", "react-app-rewired": "2.1.8", "react-scripts": "4.0.3",

I am using CRA v3 with customize-cra-react-refresh and everything works fine, but wanna new cra4

shovon commented 3 years ago

Have the same error - HMR not work - only if I set in .env FAST_REFRESH=false But I want to have HMR in my projects....

"customize-cra": "1.0.0", "react-app-rewired": "2.1.8", "react-scripts": "4.0.3",

I am using CRA v3 with customize-cra-react-refresh and everything works fine, but wanna new cra4

Why not Fast Refresh? Why HMR?

Aledosim commented 3 years ago

Hello! I've been using it with babel-plugin-rewire. When I run npm start, got:

./src/components/Background.js
TypeError: /usr/local/home/username/Development/bitinforma/src/components/Background.js: Property local of ImportDefaultSpecifier expected node to be of a type ["Identifier"] but instead got "CallExpression"

Since I just need it for my tests, I can run react-scripts for start and react-app-rewired for test. Didn't tried with build.

timarney commented 2 years ago

Should be compatible up to v5 now https://github.com/timarney/react-app-rewired/pull/530#issuecomment-1001025219