I like styled-jsx. I build a GatsbyJS starter with it.
If you do not know, GatsbyJS is a static site generator for ReactJS.
I assume you know what styled-jsx is, otherwise you would not be interested in the title. Just in case, styled-jsx is a 'CSS in JS' library.
As I wrote, I got some experience with styled-jsx working with GatsbyJS, but a couple of days ago I wanted to use the library in an app based on create-react-app. I am pretty sure you know what create-react-app is. :)
There was one problem however.
To make styled-jsx work we have to edit the project's babel config. Nothing complicated, but create-react-app does not allow any changes like that, without ejecting. Ejecting however was not a thing I wanted.
I got stuck.
React App Rewired
Fortunately, react-app-rewired came to the rescue.
Tweak the create-react-app webpack config(s) without using 'eject' and without creating a fork of the react-scripts. All the benefits of create-react-app without the limitations of "no config". You can add plugins, loaders whatever you need.
So let's make styled-jsx work in an unejected create-react-app based application.
Rewire create-react-app to use styled-jsx
First, create an app with create-react-app
.
npx create-react-app my-styled-jsx-app
Move to the newly created folder.
cd my-styled-jsx-app
Then install react-app-rewire
as a dev dependency.
yarn add react-app-rewired --dev
And styled-jsx
as a dependency.
yarn add styled-jsx
It's time to rewire create-react-app
. Open the package.js
file and edit from this...
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", }
... to this.
"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test --env=jsdom" }
Now we are able to edit the babel
's config, as we want.
Create a new file called config-overrides.js
in the root directory of the app.
const { injectBabelPlugin } = require("react-app-rewired"); module.exports = function override(config, env) { config = injectBabelPlugin(["styled-jsx/babel"], config); return config; };
That's it. We have an app build on create-react-app
in which we can use styled-jsx
without ejecting.
Restyle the app with styled-jsx
Move CSS style rules from outer css files into the App
component's file.
import React, { Component } from "react"; import logo from "./logo.svg"; class App extends Component { render() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Welcome to React</h1> </header> <p className="App-intro"> To get started, edit <code>src/App.js</code> and save to reload. </p> {`/* global styles */`} <style jsx global> {` body { margin: 0; padding: 0; font-family: sans-serif; } `} </style> {`/* local styles */`} <style jsx>{` .App { text-align: center; } .App-logo { animation: App-logo-spin infinite 20s linear; height: 80px; } .App-header { background-color: #222; height: 150px; padding: 20px; color: white; } .App-title { font-size: 1.5em; } .App-intro { font-size: large; } @keyframes App-logo-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } `}</style>` </div> ); } } export default App;
Clearing
The last thing to do is to make some clearing.
Remove needless CSS files.
remove src/index.css scr/App.css
And their import
statements from App.js
and index.js
.
Demo
There is a repo on Github - example-create-react-app-styled-jsx - with a live demo.
Top comments (2)
Looked promising, but be warned: react-app-rewired doesn't support create-react-app v2, and they have no plan to do so.
I tried one of the alternatives - craco (Create React App Configuration Override) - but unfortunately it's broken at the moment following a change in how create-react-app organises its webpack configs: github.com/sharegate/craco/issues/61
So I'm sticking to Aphrodite for the moment for CSS-in-JS, as it doesn't require any special Babel configuration.
Awesome! Thanks, Greg.