React (CRA) with custom react-scripts
Doing a create-react-app with custom react-scripts, and without craco or ejecting.
Customizing react-scripts without ejecting
As many other developers I also had to add customizations to webpack config of my CRA.
When you start searching on the Internet for solutions, most will guide you in using libraries like craco..
And the official Alternative to Ejecting, which suggests to fork the create-react-app
repository. This would be the good alternative when reusing the same custom configuration over and over, and you don't want to eject your create react application.
Well, I will propose a new and different solution, which can help customize the react-script without ejecting and not having to fork the repo for a single project.
So, first you need to have these prerequisites:
- NodeJs 16+ (lts)
npm install -g create-react-app@5.0.0
(is the latest version to date)- know how the work the tools and how to configure them.
React App
For the demo we will setup a plain cra with the typescript template.
Just run create-react-app cra5-demo --template typescript
.
And now add some magic.
Customizing react-scripts
for this you will edit the package.json
file and add workspaces.
{
"dependencies" : {
"react-scripts": "*" // replace '5.0.0' with '*'
},
"workspaces": [
"packages/react-scripts"
]
}
Next step is to get a copy of react-scripts
, you could take it from your current node_modules/react-scripts
but theres a better way.
We will just use the tarball npm view react-scripts dist.tarball
This can be done using npm pack
and then tar -xzf
.
$ mkdir packages
$ npm pack react-scripts --pack-destination packages/
$ cd packages
$ tar -xzf ./react-scripts-5.0.0.tgz
$ ren package react-scripts
$ del ./react-scripts-5.0.0.tgz
The tar
command will extract the contents of the package tarball downloaded from the NPM registry. The name of the extracted folder is package/
- this is likely because it's the default behavior of npm pack
when npm packs a package folder - link to source.
You should now be able to make changes to packages/react-scripts/config/webpack.config.js
and than run npm install
from the root project.
Final thoughts
Using the monorepo principals really helped me solve this issue. Using libraries like craco, which is not maintained anymore, try to solve this by altering node_modules/react-scripts
by using scripts and extra configuration-files to manipulate the module before executing the react-scripts. This seems a bit brute force, and in my opinion having a workspace module be linked in to you node_modules is a cleaner solution.
When you have the need to automate or reuse the changes to your react-scripts configuration, then I would suggest, you create a fork and just copy in the current changes, or even better to create a custom template that will includes a workspace for react-scripts.