Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parcel: using separate SCSS files for each React component, but with a variables file

I'm trying to find my way in setting up an efficient web development workflow even though I am new to React and bundlers (and the combi of these two). My goal is to have each React component use its own SCSS file, which can't be accessed by other components' stylesheets. There needs to be some global files though, like a variables.scss, which is where the problem lies.

This is how my file structure (from the src folder) looks at the moment:

├── assets
├── components
│   ├── App
│   │   ├── index.js
│   │   └── index.scss
│   ├── Taskbar
│   │   ├── index.js
│   │   └── index.scss
│   └── Window
│       ├── index.js
│       └── index.scss
├── index.js
└── sass
    ├── mixins.scss
    └── variables.scss

I'm using Parcel with node-sass to import these SCSS files. As you can see, each component has its own folder with a SCSS file in it.

Each component loads its designated stylesheet like this:

import React from 'react';
import './index.scss';
import Taskbar from '../Taskbar';

export default class App extends React.Component {
  render() {
    return (
      <div id="app">
        <Taskbar />
      </div>
    )
  }
}

I like to keep this approach, as the stylesheets are only used if the components themselves are imported.

The problem

If you take one more look at my file structure, there are two files in the sass folder (variables.scss and mixins.scss). I want all the files in that folder to be accessible to all components.

I've tried to just plain simple import the files in the App, so it can be accessed in all files, like so:

import '../../sass/variables.scss';
import '../../sass/mixins.scss';

These do load of course, but I can't use the variables and functions declared in these files in, for example, Taskbar/index.scss.

So that would make my question: How do I use these global sass variables/functions in "protected" SCSS files?

like image 722
easybakeoven4 Avatar asked Sep 07 '19 00:09

easybakeoven4


1 Answers

Welcome to stackoverflow! Great first post. Very informative, clear and to the point.

Ideally your shared SCSS will be partials and you will use the @import syntax instead of import.

From the Sass guide:

You can create partial Sass files that contain little snippets of CSS that you can include in other Sass files. This is a great way to modularize your CSS and help keep things easier to maintain. A partial is simply a Sass file named with a leading underscore. You might name it something like _partial.scss. The underscore lets Sass know that the file is only a partial file and that it should not be generated into a CSS file. Sass partials are used with the @import directive.

Working example:

Edit React Parcel with SASS imports


Some additional notes...

A subjectively "better" folder structure (see notes below for why):

  └── src
      ├── assets
      ├── components
      |   |
      │   ├── App
      |   |   ├── __tests__
      |   |   |   └── App.test.js
      │   │   ├── index.js
      │   │   └── styles.scss (App.scss)
      |   |
      │   ├── Taskbar
      |   |   ├── __tests__
      |   |   |   └── Taskbar.test.js
      │   │   ├── index.js
      │   │   └── styles.scss (Taskbar.scss)
      |   |
      │   └── Window
      |       ├── __tests__
      |       |   └── Window.test.js
      │       ├── index.js
      │       └── styles.scss (Window.scss)
      |
      ├── styles
      |   ├── _mixins.scss
      |   ├── _variables.scss
      |   └── styles.scss (exports all shared partials)
      |
      └── index.js
  • Avoid using index.scss for component-level stylesheets because when you start adding tests, you'll confuse Webpack as to which import you want if you just write import Component from "./index" without an extension. This has a 50/50 chance of throwing export is not a class or function errors. As a general rule of thumb, I will either use the same name as the parent folder or use styles and add the .scss extension to the import to differentiate that its unique from a normal .js import.
  • Optional: You can import partials into a single non-partial file and import that file into each component-level stylesheet. See my example here. This saves some time from writing multiple @import statements over and over for each component-level stylesheet; but, has the disadvantage of importing everything when you may only want one thing.

And... if you're bored and have some time, I go into detail as to why I like this folder structure.

like image 77
Matt Carlotta Avatar answered Sep 30 '22 18:09

Matt Carlotta