I recently worked on an issue on Create React App (CRA) for which I needed to understand the basic control flow of CRA. Dan Abramov was kind enough to give me a very detailed overview of what was going on & I though it’ll be useful for prospective contributors & also save him a lot of trouble if I can pen all that inform in this blog post to the best of my ability.
All the meat of the CRA mainly lives in a package called react-scripts. It is installed as a dependency in your application’s node_modules folder. This package contains scripts for the building, testing, starting your app. The bin script is responsible to calling the respective scripts. When you do an npm install in the root folder of your application, npm creates a symlink in your node_modules/.bin folder to the react-script.js so that it can be directly used from the CLI. Projects generated using CRA use these scripts to test, run & build the application.
There are several ways in which CRA can be used to generate your React project:
The whole purpose of CRA was to help make React apps without a pre-defined configuration so that the developers can focus primarily on the “React” part of the application rather than spend hours learning & researching about the various configuration options available & still not ending up with something that addresses their needs. Keeping this in mind, CRA was primarily made to be non-configurable. The upside of using this method is that all the updates to react-scripts in the upstream repository can be integrated in your project easily. This represents one extreme of the spectrum.
The other end of the spectrum is a very drastic way to tweak the configuration of the CRA.
- This method can be used by running npm run eject which executes a script called eject.js inside the react-scripts package.
- This removes the react-scripts dependency from your project completely, and copies all scripts and config files right into your project as separate dependencies like Babel, Webpack, etc.
- The package.json of your application is also rewritten since react-scripts no longer exist & hence, to be be able to run, test & build the app, we put all of those scripts in scripts/ so that they can be referenced in the scripts object in package.json
- The major downside of this is that once your eject your scripts, it cannot be undone & you’re all on your own — managing your own dependencies and config files — you cannot take advantage of the updates that come to react-scripts over time
If you want to tweak your CRA config only slightly, then ejecting your scripts is an extreme measure with a lot of downsides. Another alternative to that is to create your own fork of react-scripts & use that in your application. The steps do to so are as follows:
- Fork react-scripts & tweak the configuration to suits your needs. Let’s call the new fork as react-scripts-fork.Change the name in the package.json ofreact-scripts
- Publish your react-scripts-fork to npm
- Create your react app using
$ create-react-app my-app --scripts-version react-scripts-fork
- This will install your tweaked react-scripts into the your application’s node_modules/ directory
- Everything else like npm start, npm test, npm run build works as it does with react-scripts out of the box
- This upside of this approach is you’re not all on your own with configs & dependencies strewn all over the place
- The downside is that you need to maintain it on your own & merge changes from upstream manually
P.S.- Most of what’s written above is in Dan’s words & I’ve merely tried to create a gist of everything that I understood. Hope this helps!
This post was originally published on medium.com