Tania Shulga
Tania Shulga

Reputation: 228

React Styled Components stripped out from production build

I use Styled Components as CSS alternative for my React App. In development everything works fine (first screenshot), but when I run a production build (npm build), styles within style tags are stripped out (second screenshot). As a result, there're no styles in the production build.

development

production

Here is the production version: http://projects.loratadin.com.s3-website-us-east-1.amazonaws.com/weather-app/

Here is the source code: https://github.com/Loratadin/weather-app

Upvotes: 4

Views: 10262

Answers (3)

GavKilbride
GavKilbride

Reputation: 1569

For the Create React App folks out there you can add a .env file in your root and add:

REACT_APP_SC_DISABLE_SPEEDY=true

Upvotes: 5

Youssef Kababe
Youssef Kababe

Reputation: 241

I had a similar issue with empty style tags in production. I'm using a headless browser for server-side rendering and this issue caused the server-side rendered pages to appear with no styles before JS assets are loaded.

After a lot of searching around, I finally found out the reason. The Styled Components library uses something called the "Speedy mode" to inject styles on production. This makes the styles bypass the DOM` and be injected directly inside the CSSOM, thus, appearing in the inspector, but totally invisible on the DOM.

Fortunately, Styled Components 4.1.0 came with a fix for this issue! Now you can set a global variable called SC_DISABLE_SPEEDY to true in order to disable the Speedy mode and get the styles to appear on Production as well. Keep in mind that you should do it at the very beginning of your application's entry file, before importing any styled component, otherwise it will not work.

The way I did it is by creating a new file called globals.js that contains global.SC_DISABLE_SPEEDY = true and importing it as the very first thing in my index.js.

Reference: https://www.styled-components.com/releases#v4.1.0

Upvotes: 18

Matt Carlotta
Matt Carlotta

Reputation: 19762

I was able to replicate your issue and it looks like when the application is in production, it can't select html elements within a styled component (the styles don't apply to the element). Instead, you'll need to create additional stylized components for input and button.

Working example: https://github.com/mattcarlotta/Weather-App

I refactored your application to simplify its structure. Please read the README for instructions on how to run it in development and in production (DO NOT use the above repository for production, as it's highly unnecessary to have an express backend -- I only did this so that you can run a local production build).

What I changed:

  • Moved any styled components to the components folder for modularity
  • Any sort of global stylization was put into a styles folder
  • Moved assets to images and imported them into the styled component that needed them (eliminating the need to use require('../path/to/image'))
  • Simplified the App.js file. Children are controlled by state and class methods. Most importantly, turned your form into a controlled component, fixed the getWeather method to: Not allow an empty submission, if the AJAX calls fails, it'll catch the error (instead of breaking your app), and reset the form inputs on successful submission.
  • Added prop-types to ensure props were consistent in declaration (string remains a string, number remains a number, and so on).

Upvotes: 4

Related Questions