Can we please use the create-react-app?
I was very restrained regarding the create-react-app tool because, you know, I have my habits as we all do. I like custom configuration that isn’t possible with create-react-app, and this was a little confusing for me. I didn’t want to change my habits, and I guess that’s why I didn’t want to take a closer look at the create-react-app library. At the same time, I like the CLI tools in Preact or new Angular.
Let’s look at the barriers for me and why I like to work with the create-react-app now. Here are some pros and also later the cons of this approach. I guess this blog post is for the unconvinced people. I hope that it will help you to decide whether to use the tool or not. It’s important to mention that this isn’t a tool for every use case, but let’s assume that we’ll think about standard single-page apps built with React.
First things first – short introduction of the tool
Create-react-app is a set of tools, including a command-line tool, which allows you to create a React project with a custom scaffold and a run development server for your app. It is all based on Webpack, but what is incredible is that you don’t need to touch the Webpack configuration at all. Everything works. It is something similar to the Angular CLI, Preact CLI tool, or Ember CLI. It was always a pain to configure a custom Webpack setup and then optimize it for production. It isn’t complicated but time-consuming. Copying my boilerplate is also annoying. So, create-react-app seems to be an obvious choice, right? Not for all, of course. I’ll talk about it later.
Why such title?
Of course, the title is just my wish. Why? Because when we all start using official scaffold tools, we will be able to change teams, projects, and companies with ease. I mean us as JavaScript developers. We will get standards at the beginning of every project. For me, it would be much simpler to join a project which uses the same tools as my previous project/team - or at least some common fundamentals. So standards are excellent in that context. Of course, you can say that this is just a build tool, development server, and that’s it. So why do I have a problem with that, right? But when we think about all the different choices made using create-react-app, we may end up with a very similar stack in many other projects. I think that’s nice.
Good ‘ole JavaScript fatigue
We - JavaScript developers - all know this phrase. In our day-to-day work, we always need to decide which tools we should use, which will be the best, and that’s ok, but sometimes many of them are good, and what then? What should we choose then? And even if we choose something which we’re familiar with, what about other developers? They could have a hard time when joining the projects. So maybe we could break some of our habits and try to use and improve some common toolset which is also good? It could be a little bit different, but we’ll probably achieve the same effect in the end. And I mean official tools which the community and creators of the main library promote. By the way, I recommend you the talk by Dan Abramov about an approach to tooling and project configuration in JavaScript.
Why do you think it’s better than my custom Webpack configuration?
Of course, I can’t answer this question without knowing all possible Webpack configurations (which is impossible). Still, I understand that the Webpack configuration from create-react-app is well prepared, production-ready, and battle-tested. So that’s why you could try to use it. And it is probably better than your boilerplate. If I’m wrong, please show me your work. I would love to use your tools too.
Ok, what if I need custom Webpack changes?
That is an essential part of this article. For me, it was always problematic to decide to use create-react-app.
Styles management wasn’t the only barrier for me. I didn’t feel comfortable without access to my Webpack configuration. I’ve tried to go back to this tool a couple of times. I watched many talks about it, and then I started to understand why this tool is built that way and why it doesn’t support many customs approaches for styles and other tools (I know that this could change in version 2.0 – even better, right?). These approaches can be problematic in the future, and support for them in this kind of tool might be almost impossible. That’s probably the main goal for it - to have the set of tools and approaches which are most common and most used in the community and at the same time set aside others that could be problematic and also make the maintenance of the primary tool very hard. At the same time, it keeps the balance between options and care.
I found that it can be more valuable to break some of my habits and switch to other more generic approaches. Instead of some style approaches like CSS Modules, I can use CSS in JavaScript or even standard simple CSS, which has much more possibilities nowadays. I found out that, in most cases, I don’t even need preprocessors, the same with PostCSS. I usually use it only for Autoprefixer, and create-react-app has it preconfigured, so why bother with that? These are just examples, but it shows that sometimes it’s better to rethink some habits.
But let’s go back to the main topic. What if I need to change my Webpack config anyway? Create-react-app allows you to ‘eject’ from its frames, and it’ll generate custom configuration files that you can change. Of course, you won’t be able to go back to the previous state of your project. You’ll have a custom Webpack based React app from this point. This is the recommended and official way of doing that. Of course, you should do it only when there is no other way and you need customizations. It would be best if you were sure that you’ll be able to handle the project from now on without using the create-react-app CLI tool.
I don’t want to ‘eject’, is there another way?
The second way is good, but you need to know that it isn’t an official solution, and you need to be aware of that. I firmly recommend not using any third-party tools because you can achieve almost everything with the standard create-react-app, but I want to show you the solution which could help you decide to use create-react-app in general.
If you don’t want to eject using create-react-app, and at the same time you want to improve Webpack config, add some loaders or change the configuration, you can do that using react-app-rewired. This will replace the standard react-scripts library used by create-react-app, and you’ll gain the option to enhance the Webpack configuration without ‘ejecting’.
Again, as you can read in the documentation, you need to be aware that you’ll break some basic assumptions provided by create-react-app. So I guess you need to use it only for a crucial part of your project.
As for me, I use it sometimes in projects, for example, when using Ant Design, and it all works very well for me. But it is always better to use just what create-react-app gives you. It’ll always be simpler to debug your workflow and ask for help in the community, which is very big.
So what you need to do is install react-app-rewired, and then you need to replace react-scripts with the react-app-rewired library. Then you can use a special config-overrides.js file and provide your config overwrites. You’ll find much more in the documentation.
Let’s sum up
Create-react-app is a perfect tool when you want to keep the same approach in many projects, and you want to have a very performant and quick start. It is suitable for all single-page apps built with React. It is also good because it ‘forces’ the developers to use some battle-tested approaches, configuration, and tools. When you want to keep changing your Webpack structure, you can use a third-party library or find other suitable tools. You’ll find them in the official create-react-app documentation.
From version 2.0 of the library, we might have some of the missing puzzle pieces like CSS Modules or SCSS preprocessing, which is great news. Read more about it here.
Please let me know how long you’ve used the tool and whether you like it or not. I’m also curious how many times you need to ‘eject’ in projects.