We currently have two main options when using CRA:
| | Upate | Custom Config |
| ---: | :---: | :---: |
| not eject | ✅ | ❌ |
| eject | ❌ | ✅ |
There is a third option which is to maintain a fork of react-scripts (like create-react-app-typescript does ). The downside here is that you have to merge all the changes made on create-react-app and lerna make the whole things a bit messy in my opinion (because you have to fork all packages to publish only one of them).
Finally, there is a fourth option which consists of copying the scripts folder in your app to edit the webpack config object before using it ( example repo here ).
But as pointed by @gaearon in this tweet, this solution is incompatible with semver and a minor update to react-scripts could break your app because the configuration is locked down and could change at any moment.
As a way to make the last solution more viable and safe, the proposal is to expose the webpack configuration object as a standalone package that would follow semver.
This would allow to both extends the CRA config (with the method above) or use it in other contexts than CRA.
It might also be useful to expose the object as a webpack-chain object since it's not always easy to edit a raw webpack config.
Thoughts ?
What are some use cases for editing a config like this?
I think most reason to eject are valid use cases :
In my case I'm using this method to support a custom async module loader I've made (multiple entry points and setting output.library).
In another project I've used this to add fork-ts-checker-webpack-plugin to react-scripts-ts.
If we decide to support this, we might as well support overriding config in non-ejected projects. Because in practice people don’t really look at major versions of transitive dependencies. If they see direct modification of webpack config in one repo they’ll do it everywhere (and thus can misunderstand semver guarantees and get confused why their stuff breaks in patch releases).
Maybe now is a good time to start adding escape hatches that let you modify config? If it is, how do we communicate that you forgo semver guarantees once you do this?
I’m thinking something like dangerouslyOverrideConfigs.js in the root folder.
Um... right,
What if we do add an eject-but-not-really scripts that just create that dangerouslyOverrideConfigs.js and add the config package ( let's call it react-scripts-config ) as a dependency ?
We could then add the version of react-scripts-config as a property of the exported object and react-scripts could then check that the config passed as output of dangerouslyOverrideConfigs.js is of the correct version and display some explanation when it's not.
This way, if the user updates react-scripts but nor react-scripts-config he get an error : You also need to update react-scripts-config.
Same if he update only react-scripts-config.
And since react-scripts-config is a dependency, it's up to the user to make sure nothing breaks...
Just to throw out a thought: I know that _one_ of the reasons for keeping all the Webpack config locked away was the hypothetical idea that CRA _might_ someday base its internals on another bundler instead. Is that still a meaningful concern?
I think it's less likely today given that webpack has improved in many areas but we still prefer if most newly created apps don't immediately tie themselves to webpack-isms.
Im using https://github.com/timarney/react-app-rewired in a big cra app which more ore less does the above except the config file is just called config-overrides.js :). I also wrote some plugins for it. I think the approach is legit. Ruzzle is using a similar pattern. In a toying project I actually changed from rewired override to ruzzle override with minimal effort and I think users of CRA would enjoy a pattern where they dont feel tied.
https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-service/package.json
https://github.com/mozilla-neutrino/webpack-chain
The way vue cli 3 does it is pretty cool
Definitely vue cli v3 figured how to properly do this without that much trade off.
Most helpful comment
If we decide to support this, we might as well support overriding config in non-ejected projects. Because in practice people don’t really look at major versions of transitive dependencies. If they see direct modification of webpack config in one repo they’ll do it everywhere (and thus can misunderstand semver guarantees and get confused why their stuff breaks in patch releases).
Maybe now is a good time to start adding escape hatches that let you modify config? If it is, how do we communicate that you forgo semver guarantees once you do this?
I’m thinking something like
dangerouslyOverrideConfigs.jsin the root folder.