Selenir
Selenir

Reputation: 718

Accessing global variables in Sass with Webpack without multiple imports

I'm developing an application with React using Bootstrap 4 with Sass and webpack for building, every React component has it's own .scss file.

I've run into a problem, where I need to use Bootstrap's variables, but I can't import bootstrap because I end up with Bootstrap imported multiple times (apart from performance issues duplicate imports keep overriding my changes to Bootstrap's rules)

My main two problems are:

  1. ComponentA stylesheet has to access Bootstrap's variables and mixins (i.e. button-variant), to achieve that I have to @import Bootstrap inside my .scss file (otherwise I end up getting undefined variable errors).
  2. Adding @import '~bootstrap' to every component's stylesheet results in importing whole Bootstrap multiple times. So when I override a variable, i.e. $body-bg in my global.scss file, which contains shared styles, it only uses my value in first import, what means that every succeeding Bootstrap import doesn't get my variables, and keeps overriding it with defaults.

Are there any methods for dealing with that kind of problems? My guess would be to somehow enable "global scope", so I can use variables/mixins without continously importing whole Bootstrap.

Edit: I've found a workaround, when Sass files are imported from other Sass file, the variables are accessible, so creating a single big import.scss file instead of using separate imports from .js files seems to work.

Upvotes: 5

Views: 3181

Answers (2)

Sebastien Horin
Sebastien Horin

Reputation: 11067

There is no better solution than replacing the old @import by the new @use, and everything should be imported once only

https://sass-lang.com/documentation/at-rules/import

Upvotes: 0

Guillaume
Guillaume

Reputation: 3051

Had the same issue, managed to resolve it by creating a file bootstrap.imports.scss that imports my custom variables and the mixins, variables etc. from bootstrap:

@import 'bootstrap_variables'; // contains the custom bootstrap variables

@import '~bootstrap/scss/functions';
@import '~bootstrap/scss/variables';
@import '~bootstrap/scss/mixins';

Then in the webpack config I use the sass-resources-loader loader like this:

rules: [{
  test: /\.(scss)$/,
  loaders: ExtractTextPlugin.extract({
    fallback: 'style-loader', // in case the ExtractTextPlugin is disabled, inject CSS to <HEAD>
    use: [{
      loader: 'css-loader', // translates CSS into CommonJS modules
      options: {
        sourceMap: true
      }
    },
    {
      loader: 'postcss-loader', // Run post css actions
      options: {
        sourceMap: true,
        plugins: function () { // post css plugins, can be exported to postcss.config.js
          return [
            require('postcss-flexbugs-fixes'),
            require('autoprefixer')
          ];
        }
      }
    },
    {
      loader: 'sass-loader', // compiles SASS to CSS
      options: {
        sourceMap: true
      }
    },
    {
      loader: 'sass-resources-loader',
      options: {
        resources: [
          `${path}/bootstrap.imports.scss`
        ]
      },
    }]
  })
}]

With this, I am able to import a scss file anywhere and use the botostrap functions or variables

Upvotes: 2

Related Questions