Enabling styled-components' debugging options in your CRA app without ejecting
Tags: styledcomponents, debugging, typescript, createreactapp
Published: 2020-04-11 00:08:28

---
title: Enabling styled-components' debugging options in your CRA app without ejecting
published: true
description: Enable debugging options (e.g. `displayName` and `ssr`) from styled-components in your CRA (create-react-app) application.
tags: styled-components, debugging, typescript, create-react-app
---

I have a project using CRA ([`create-react-app`](https://github.com/facebook/create-react-app)), TypeScript and [`styled-components`](https://styled-components.com/).

`styled-components` has a useful feature when you are developing your components: a debugging option called `displayName` that shows the components' name in the generated CSS classes. It helps you to identify each component in your DevTools.

According to the [docs](https://styled-components.com/docs/tooling#babel-plugin), to enable it, you need to use a **Babel plugin**.

> The [docs](https://styled-components.com/docs/tooling#typescript-plugin) says we need a different plugin if we are using TypeScript. However, it is **not the case**, even if your project uses CRA + TypeScript, as mine does.

However, CRA doesn't have a `.babelrc` file. It seems that its Babel configuration is given through the webpack config.

It brings another problem: CRA doesn't support a custom webpack config unless you "hack it".

So we need to follow two steps:

- **1. Find a way to modify CRA's default webpack config.**
- **2. Add the Babel plugin.**

### Customizing CRA's default webpack config

There is an awesome package called [`react-app-rewired`](https://github.com/timarney/react-app-rewired) that allows you to extend the default webpack config.

```
$ yarn add -D react-app-rewired
```

You create a file named `config-override.js` (at the root path) that acts similarly to the webpack config file. 

```js
// config-override.js
module.exports = function(config) {
  // `config` is the default config. Do whatever you want.
  return config;
}
```

If we have the default webpack config, all we have to do now is to find out which rule we should modify to add the extra Babel plugin.

However, there is also a tiny package that makes this task easier: the `customize-cra`.

### Injecting the Babel plugin

The [`customize-cra`](https://github.com/arackaf/customize-cra) package is a set of utility functions that helps you extend some config from CRA. Let's say these functions basically "change the right object properties for you".

```
$ yarn add -D customize-cra
```

Then update your `config-override.js` file to inject the Babel plugin:


```js
const { override, addBabelPlugin } = require('customize-cra')

module.exports = override(
  addBabelPlugin(
    ['babel-plugin-styled-components', {
      displayName: true,
      // any extra config from babel-plugin-styled-components
    }]
  )
)
```

### Updating your dev / build scripts

The final step is simple: you need the modify the default npm scripts in your `package.json` so they can use `config-override.js` rather than the default webpack config.

```json
{
  "name": "your-app",
  "version": "0.1.0",
  "private": true,
  // ... omitted for brevity purposes
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject" // No need to change it for `eject` command
  },
}
```

### Conclusion

Well, that's it! 🚀 I don't fully understand how webpack works internally, so even this simple thing took me some time to figure out. I hope it helps someone else.