Jian Weihang Jian Weihang -3 years ago 174
React JSX Question

Should global css be put in each component or the root component (webpack entry file)?

I am wondering that if I have an external CSS file which is frequently used in my components, should I import this external CSS inside each component or the root component?

For each component:

import React from 'react'
import '../font.css'

class MyComponent extends React.Component {
render() {
return <div className="fa fa-bandcamp"></div>;
}
}


This is self-explanatory: because I want to use 'fa fa-bandcamp', I import '../font.css'.

This methodology is just like programming JS or any other programming languages. If we need a dependency, we import it in that file as well, for example:

import global from 'global'
import util from 'util'

global.foo
global.bar
util.bar
util.bar
// ...


However, my colleague told me that global css should never be imported inside every depending components, instead, it should be imported inside a root component or in the entry file of webpack, for example:

// in each component
import React from 'react'
// import '../font.css'

class MyComponent extends React.Component {
render() {
return <div className="fa fa-bandcamp"></div>;
}
}

// in entry file (root component)
import React from 'react'
import '../font.css'

class App extends React.Component {
render() {
return <div>{this.props.children}</div>;
}
}


What's the pros and cons of each solution? I would like to hear more advices and appreciate your help.

Answer Source

I'd import your font.css file when and where you use it (but not exactly the way you suggest, see below) and not just in the root component. I suggest this because when and if you decide to code split, you would only want that CSS to exist in the bundle that uses it.

If the import is in your root component, you might remove all components that are using the fa fa-bandcamp classes but your import remains in the root (because you forget it's there and not alongside your component) and you'd be bundling in CSS that is not even in the chunk that uses it.

On the contrary though, when importing at the component level you could also end up in a situation where you use those classes and forget to import that font.css because ANOTHER component has imported the global CSS already. It looks like it works but if you code split you might find that your chunk does not have the right font because the CSS import is in another chunk. In this case importing it in the root would have solved your issue!

What I would do:

I would argue that any global css is bad and you should be using something like CSS modules. So I'd go one step further and create a <Text/> component that is something like:

import React from 'react'
import '../font.css'
export default ({ className, children, tagName: TagName }) => <TagName className={`fa fa-bandcamp ${className}`>{ children }</TagName>;

Now you can use the <Text tagName="span">Hey!</Text> in all your components safely because:

  • You no longer have to import the CSS all the time.
  • If you code split, or remove all <Text/> you won't be left with a bundle that contains unused CSS imports in the root that you forgot about.
  • It's not possible to use those classes and forget to import the CSS.
  • Everything is nice and encapsulated in a modular way and your bundles are as efficient as possible.

I wouldn't employ this kind of strategy for something like a reset.css though. Obviously.

TL;DR Summary

Root level - Potential inefficient code splitting. Harder to maintain as CSS does not live along side the component that uses it.

Individual component level - Pain to import all the time. Fragile as you can end up using a class that doesn't exist in a chunk if forgetting to import the global CSS.

"Text" component - Awesome. Just make sure everybody uses the fa classes via this component and everything is golden. Modular. Easy to maintain. Durable.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download