1

Im currently working on a react project and im using sass. When im starting the project everything works and i can see that the variables that i defined are being used correctly. Even so when im starting the app or just saving and getting a new render the screen is filled with a bunch of errors like this one:


Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined variable.
  ╷
9 │     background-color: $clr1;
  │                       ^^^^^
  ╵
  src\assets\scss\basics\_buttons.scss 9:23  root stylesheet

styles.scss

// setup
@import "./setup/variables";
@import "./setup/functions";
@import "./setup/mixins";
@import "./setup/layout";

// basics
@import "./basics/helpers";
@import "./basics/base";
@import "./basics/buttons";

// cmps
@import "./cmps/back-button";
@import "./cmps/footer";
@import "./cmps/header";
@import "./cmps/selected-quotes";

//views

@import "./views/about";
@import "./views/homepage";
@import "./views/share";
@import "./views/story-check";
@import "./views/template-edit2";
@import "./views/testimony";
@import "./views/story-upload";

//QUOTE
@import "./cmps/quote/quote-preview";
@import "./cmps/quote/quote-list";
@import "./cmps/quote/quote-tags";
@import "./cmps/quote/quote-toolbar";
@import "./cmps/quote/quote-filter";
@import "./cmps/quote/paging/paging";

_variables.scss

// colors
$clr1: #CD531F;
$clr2: #a7c6d3;
$clr3: #3F3F3F;

// layouts
$layoutPadding: 20px;
// breakpoints
$break-narrow: 490px;
$break-585: 585px;
$break-normal: 760px;
$break-wide: 960px;
$padded-break-narrow: $break-narrow+$layoutPadding * 2;
$padded-break-normal: $break-normal+$layoutPadding * 2;
$padded-break-wide: $break-wide+$layoutPadding * 2;

_buttons.scss

button {
    cursor: pointer;
}

.primary-btn {
    padding: 16px;
    background-color: $clr1;
    color: white;
    border-radius: 4px;
    border: none;
    font-weight: bold;
    font-size: rem(14px);

    &:hover {
        background-color: $clr1;
        color: white;
    }
}

index.js(where i import the main styles file)

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux';


import { store } from './store/store'
import './assets/scss/styles.scss'
// import reportWebVitals from './reportWebVitals';

import { RootCmp as App } from './root-cmp'

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <Provider store={store}>
    <Router>
      <App />
    </Router>
  </Provider>

)

Here are the things that i have tried:

  1. importing the styles file in the App component
  2. checked all the file names(all of them have _ at the begining)
  3. made sure _variables.scss is imported at the top of styles.scss

one thing that did work: when i import _variables.scss inside _buttons.scss there are no errors but i dont want to have to import the variables file everutime i want to use a variable.

Any suggestions??

Avi9022
  • 9
  • 2

1 Answers1

1

This is quite unintuitive hence why you've understandably fell into the trap, but the variables defined in _variables cant actually be seen by _button since they are not really global -- they are scoped to the file.

You can fix by importing _variables into _button:

@import "../setup/variables";

button {
    cursor: pointer;
}

.primary-btn {
    padding: 16px;
    background-color: $clr1;
    color: white;
    border-radius: 4px;
    border: none;
    font-weight: bold;
    font-size: rem(14px);

    &:hover {
        background-color: $clr1;
        color: white;
    }
}

However, its notable this is only because sass-loader in webpack demands a different pattern. In sass on the CLI, it doesn't need this it's all global.

This difference is frustrating but you can use http://github.com/shakacode/sass-resources-loader to restore the old behaviour if you want with some config work.

Alternatively, though I don't recommend this as you'll lose the "watch" capabilities of webpack, you could opt to instead run the actual sass CLI in your build pipeline, and import the resulting CSS in the root of your project.

At the same time, the difference in behaviour is quite purposeful. Webpack is encouraging you to think in "modules" similar to how JS files have their own scope. It shuns global variables, which can be problematic in complex projects.

If you want to use the webpack loader, you can configure it such that it runs as part of your scss pipeline.


module: {
  rules: [
    {
      test: /\.scss$/,
      use: [
        'style-loader',
        'css-loader',
        'sass-loader',
        {
          loader: 'sass-resources-loader',
          options: {
            resources: [
                './src/assets/scss/setup/_variables.scss',
                './src/assets/scss/setup/_functions.scss',
                './src/assets/scss/setup/_mixins.scss',
                './src/assets/scss/setup/_layout.scss',
            ]
          },
        },
      ],
    },
  ],
adsy
  • 8,531
  • 2
  • 20
  • 31
  • yes i have mentioned that i have done that and it works but this is not my first project using sass and i have in the past used a single vatiables file and just imported it into my main styles file. i have actually just checked a previouse project of mine and it works there perfectly – Avi9022 Aug 01 '22 at 19:43
  • Yeh I think this is because theres a difference in behaviour between sass-loader in webpack and traditional sass as executed on the command line. It kinda sucks its different -- would this explain what youre seeing? – adsy Aug 01 '22 at 19:44
  • Also you can use https://github.com/shakacode/sass-resources-loader if you want the "original" behaviour. – adsy Aug 01 '22 at 19:45
  • (and apologies, I should have read the bottom of your question, I will edit my answer to describe why its happening and the plugin) -- edit, done – adsy Aug 01 '22 at 19:49
  • its not really clear how to use it. i installed the package what should i do next? – Avi9022 Aug 01 '22 at 19:56
  • Ive added a rough config and modified the path to be roughly applicable to yours – adsy Aug 01 '22 at 19:59
  • thanks alot! im still a bit confused, where am i supposed to add these changes? – Avi9022 Aug 01 '22 at 20:05
  • This'll be in your webpack configuration, which is probably in the root of your project and probably called webpack.config.js or similiar. – adsy Aug 01 '22 at 20:05
  • Note, if you are using something like `create-react-app` you cant easily change the configuration :(. Unless you want to eject or use something like https://www.npmjs.com/package/@craco/craco. If this is applicable to your case, I'd really consider not bothering and instead importing the variables in each file. This feels like work, but it actually makes a lot of sense if adopting the webpack mindset. It's something you'll get used to, and by avoiding global variables, you improve the code: https://stackoverflow.com/questions/10525582/why-are-global-variables-considered-bad-practice – adsy Aug 01 '22 at 20:07