Create React App 2.0 has officially been released. It includes Sass and CSS Modules out of the box. Check it out here:https://reactjs.org/blog/2018/10/01/create-react-app-v2.html
If you’ve been using React for any length of time you’re probably well aware of the Create React App project. If you’re not familiar, Create React App (CRA) provides a handy CLI for spinning up a boilerplate React app. By typing
create-react-app my-app you can have a bootstrapped app running in a couple minutes. One thing you can’t do easily, is change the configuration of CRA. That is by design. Essentially the team has decided on a configuration they like and bundled it all together. The underlying config files aren’t exposed until you run
yarn run eject to eject the config. Some folks love this, some do not. Naturally, on the internet, there are opinions. Personally I really like being able to quickly spin up an app without spending a bunch of time setting up Webpack the same way, every time, or customizing a folder structure etc.
The one area that some folks, myself included, seem to struggle with is that CRA doesn’t ship with any CSS tools. This is also by design. My assumption is that the team behind CRA didn’t want to play favorites or build for every CSS tool: (Sass, Less, etc.). So it’s up to the user to add them in.
You can run the
eject script to get access to the Webpack config, and add in Sass loaders, but once you
eject you can never go back. This means you could, potentially, lose out on painless upgrades to CRA in the future.
Sass is a preprocessor that is taking our
.scss files and compiling them to
.css. Sass also lets you
--watch a folder for changes and compile your styles on the fly to
.css. This gives us an option for using Sass with CRA. We’ll configure Sass to watch our
scss folder and export
css files that we’ll
import in our CRA. Essentially CRA will never know that we’re using Sass at all.
I’ve created an updated demo repo with CRA 1.5.2 running React 16. It can be found here.
To get started, we’ll need to install Sass and then make some adjustments to the default file structure.
Sass is a
Ruby gem so you’ll need to install Ruby if you haven’t already. Ruby comes installed by default on Mac and (I believe) some Linux distros. If you’re running Windows, you can use Ruby Installer. To install Sass you can run:
gem install sass from your terminal.
A few folks have pointed out that it is not required to install Ruby to get Sass running. You have options like node-sass, and the CRA-Readme suggests using node-sass-chokidar. The method I’m outlining below is what is suggested in the Sass docs. When I started playing around with adding Sass to CRA it wasn’t documented in the Readme and I hadn’t gone back to revisit the docs recently.
I’ve added node-sass support to the demo repo. Simply check out or fork the node-sass branch. More info about node-sass is available in the readme on the demo repo.
File structure changes:
#new-folder: src/styles#new-folder: src/styles/css#new-folder: src/styles/scss#rename/move index.css: src/styles/scss/index.scss#rename & move App.css: src/styles/scss/App.scss
/src folder should now look like this:
Next we’ll update our
src/index.js file to import
index.css from the correct location. We need to change the line
import './index.css' to
import './styles/css/index.css' Our
index.js file should now look like:
We can also remove the
import ‘./App.css' line from the
App.js file. Our
App.js file should now look like:
Note: We don’t currently have an
index.css file, we’ll get to that in a moment.
Let’s update the
index.scss file. By default it has a small block of
body styling. I prefer to move that into the
App.scss file, but you could create a
Body.scss file and move it there if you’d rather. These are the default styles that ship with CRA, and you’ll likely overwrite them later anyways. Our
index.scss file only needs to import our other Sass partials. After moving the
body style block to another file, our
index.scss file should only have
@import ‘App’ and
@import 'Body' if you opted to create that file.
Our index.scss file
We’re going to use the Sass
watch mode to keep an eye on our scss folder zand have it compile our stylesheets to the css folder for us. To do that, we’ll add a script to the
"sass" : "sass --watch src/styles/scss:src/styles/css"
This tells Sass to watch the scss folder and compile output to the css folder. Now we simply open a 2nd tab in our terminal of choice and
yarn run sass to start watching/compiling our scss to css.
That’s all we need to get started! To fire up your app you’ll need to open a couple terminal processes. In one you’ll run
yarn start to start the dev server and in another you’ll run
yarn run sass to start Sass in watch mode.
2 terminal processes?! Yeah, I know, it’s not awesome that this configuration means you’ll have to have 2 processes running in the terminal while you’re developing. You’ll need the dev server along with the
sass --watch process. I’ve not found a good way around this. I’ve seen ways to automate opening separate processes but it’s all dependent on the terminal environment you’re in. I’ve not found anything universal.
The other bad part: At some point, you’re going to forget to start up the Sass process. Then you’re going to pull your hair out and probably say some choice words while you try to figure out why the changes you’re making aren’t being reflected in the browser. Just know that it’ll happen.
The first time we run our new Sass process we’ll get a bunch of new files in our css folder:
src/styles/css/App.css src/styles/css/App.css.map src/styles/css/Body.css src/styles/css/Body.css.map src/styles/css/index.css src/styles/css/index.css.map
The good news is that we never have to look inside the css folder and therefore we don’t have to care that there are so many files being created. The other good news is that Sass is smart enough to recognize changes and build new files as needed so even if you make a bunch of new files and changes before running the
sass script, once you do, it’ll output all your new
css files for you.
One last step I would recommend: add
.sass-cache to your
.gitignore file. Sass uses local cache files to track your changes, and you probably don’t want those in your repo.
That’s it! If you run
yarn start now you should have the default CRA screen showing and looking just as it should. If you want to double-check that your Sass files are indeed being compiled properly, be sure to run
yarn run sass and then maybe add a
background-color to the body.
Because we are using Sass to transpile our scss files to css files, CRA is completely unaware that we’re even writing scss. Using these methods will have no impact to the default build and deployment process of a CRA app. One thing I’ve done, on more than one occasion, is forget to transpile my stylesheets before running a new build. This is annoying. To get around this, I suggest adding another script to your
package.json that will do a one-time build of your styles:
_“sass:build”_: “sass — update src/styles/scss:src/styles/css”,
I would then suggest updating the
build script to:
_”build”_: “yarn sass:build && react-scripts build”,
This gives you one less thing to think about. Your stylesheets will automatically transpile before the build process happens.
For just a little bit of extra configuration, we get to have our cake and eat it too. We get to quickly build React apps using CRA and we get to enjoy the styling benefits that come with using Sass. Let me know if you found this to be useful. Thanks for reading!