Create React app has become the defacto standard for building React applications. With a standard comes inflexibility. The ecosystem of the JavaScript world has expanded greatly and sometimes you want to build upon the standard.
Create React App gives you options to override but it generally requires modifying heavily complex webpack configurations. Thankfully 2 packages came along to make our life a little easier. First was react-app-rewired, it provides all the low level manipulations for the Create React App webpack config. Then customize-cra utilizes it to provide high level, easier to use functions.
Once you have your Create React App project all setup we'll need to install our 2 dependencies.
npm install customize-cra react-app-rewired --dev //or yarn add customize-cra react-app-rewired --dev
Once installed we need to reconfigure our package.json
, the typical Create React App script section looks like this. It runs the react-scripts
commands. However we need it to hook into react-app-rewired
to actually redefine our configurations.
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", }
Thankfully all you need to do is swap react-scripts
out for react-app-rewired
.
"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", }
Now create a config.override.js
in the root directory, and react-app-rewired
calls it webpack configuration for Create React App.
With this config we can now run helper functions from customize-cra
. There are a TON of helpers functions you can find here https://github.com/arackaf/customize-cra/blob/master/api.md.
The one we will use is called useBabelRc
. This will allow us to tell Create React App and have Babel also utilize the .babelrc
configuration you setup.
One such use case for me was adding the preset @emotion/babel-preset-css-prop. This allows us to tag any element with css={{}}
and the babel preset will swap out the JSX pragma to use emotion.
So now create a .babelrc
and it would look like this, (after installing yarn add @emotion/babel-preset-css-prop --dev
).
{ "presets": ["@emotion/babel-preset-css-prop"] }
Then create a config.override.js
and fill it with this. The override
function takes all of the plugins you call it with and sequentially calls each one with the new configs. This builds out the final config that Create React App will use.
const { useBabelRc, override } = require("customize-cra"); module.exports = override(useBabelRc());
For us we only are using a singular plugin from customize-cra
but if you wanted to use multiple just add them as arguments to the override
function call.
const { useBabelRc, removeModuleScopePlugin, override, } = require("customize-cra"); module.exports = override(useBabelRc(), removeModuleScopePlugin());
Now you can keep all the benefits that Create React App provides while customizing to your specific needs without having to eject. As Create React App changes and react-scripts
evolves the customize-cra
and react-app-rewired
libraries could break your build and not work. So just be warned, although it has been stable for many years.