Skip to content

Webpack sass loader does not recognize global variables file #218

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
NetanelBasal opened this issue Feb 21, 2016 · 30 comments
Closed

Webpack sass loader does not recognize global variables file #218

NetanelBasal opened this issue Feb 21, 2016 · 30 comments

Comments

@NetanelBasal
Copy link

I have this sass directory:

  • _vars.scss
  • main.scss

//main.scss

@import './vars';

In other js file i have:

require('./some-module-sass-file');

The problem is I have global variables in the vars file and the some-module-sass-file not recognize them and throw an error.

@fxck
Copy link

fxck commented Mar 3, 2016

same problem, have you found any solution?

@NetanelBasal
Copy link
Author

You need to require the file in every file you need him.

@silvenon
Copy link

silvenon commented Mar 8, 2016

Yes, this is the only way. It doesn't work because variables work only within @imported Sass files. Just have a _globals.scss file with variables, functions etc. that you @import in each Sass file.

This is better anyway, because now each save won't cause all Sass files to recompile, just the file you changed.

@andrewmclagan
Copy link

although the problme with that is we end up with nest head fuck...:

"../../../../../src/_varibles.scss"

if we restructure our directories.. BOOM!

@jerrylau91
Copy link

ran into the same problem! this is so un-convenient!

@silvenon
Copy link

silvenon commented Jul 12, 2016

You could perhaps set the includePath to the directory where your stylesheet is, then import simply with @import 'variables'?

@natchiketa
Copy link

natchiketa commented Dec 13, 2016

I'm adding @import 'variables' using data:

  sassLoader: {
    data: '@import "variables";',
    includePaths: [
      path.resolve(__dirname, "./app")
    ]
  }

@evanjmg
Copy link

evanjmg commented Jan 10, 2017

Any full examples on this? I can't get this working with the examples given.

@silvenon
Copy link

@evanjmg does this help?

@evanjmg
Copy link

evanjmg commented Jan 10, 2017

No. I'm not given the file structure, @import statement, nor variable. This is only useful for node modules not including a global variables file like _variables.scss

@natchiketa
Copy link

@evanjmg That's exactly what my example does—add an import for every Sass file to a file called _variables.scss. As long as _variables.scss is in one of the paths in the includePaths array, it should work.

Beyond that I'd need to know more about your setup, such as:

  • The contents of your webpack config file
  • Where that config file is located relative to the project root
  • Where your _variables.scss is located relative to the project root

@evanjmg
Copy link

evanjmg commented Jan 11, 2017

I'm using webpack 2.1.0-beta.27 and sass loader 4.1.1 doing the following:

webpack.config.js

 loader: 'sass-loader' + SOURCE_MAP_STRING,
              options: {
                data: '@import "variables";', // I tried _variables as well
                includePaths: [path.resolve(__dirname, "src")],
                outputStyle: 'compressed',
                sourceMap: true,
                outFile: 'style.css'
              }

scss file in src/app/styles/partials/_variables.scss:
$white: #fff
and in other part of app in
src/guests/component.scss:

@import 'variables'; // get error cannot find module variables 
.guest {
   color: $white; // without @import 'variables' at the top of this file - I get $white is not defined
}

Importing relatively works fine, but I can't get these globals to work.

@silvenon
Copy link

What is SOURCE_MAP_STRING? Are you sure that you're applying options correctly?

@natchiketa
Copy link

@evanjmg Couple of things: first, although it shouldn't be an issue, since the docs say you can put the options there—I am putting them in an object called sassLoader, at the root of my webpack config's exports, like this:

module.exports = {
  ...
  module: {
    loaders: [
      {
        test: /\.scss$/,
        loaders: ["style-loader", "css-loader", "sass-loader"]
      }
    ]
  },
  sassLoader: {
    includePaths: [path.resolve(__dirname, "./some-folder")]
  }
};

The second thing is what I think is causing it to not work for you. The @import statement needs to use a path relative to one of the includePaths paths. For example, if your _variables.scss is at src/app/styles/partials/_variables.scss, and your current includePaths only has src, then the @import has to be like this: @import('./app/styles/partials/variables');. It's not just going to automatically traverse the entire tree.

Try something like this:

module.exports = {
  ...
  module: {
    loaders: [
      {
        test: /\.scss$/,
        loaders: ["style-loader", "css-loader", "sass-loader"]
      }
    ]
  },
  sassLoader: {
    data: '@import "variables";',
    includePaths: [
      path.resolve(__dirname, "./src/app/styles/partials")
    ]
  }
};

@guillaumemolter
Copy link

guillaumemolter commented Feb 16, 2017

If like me you use Vue.js with the Webpack vue-cli template, Joan Mira's blog post explains how to implement @natchiketa's solution with this stack.

@lorenzomigliorero
Copy link

data: @import '${path.resolve(__dirname, 'src', 'scss', 'import').replace(/\\/g, '/')}/variables';
This work for me, and resolve the absolute path question...

@jhnns
Copy link
Member

jhnns commented Mar 13, 2017

My advice:

Separate your Sass files into library files and application files. This means that you have Sass files that will output CSS (your application files) and you have Sass files that provide variables and mixins for them, but don't produce any output. Then you write your application files in a modular way without implicit dependencies, but explicit ones which means that you can compile any application file and it will work without producing duplicate CSS.

@eeglbalazs
Copy link

A note for webpack 2 and @natchiketa's solution:

For loader options: webpack 2 no longer allows custom properties in configuration.
Loaders should be updated to allow passing options via loader options in module.rules.

So I had to modify my webpack config like this to have global variables:

loaders: [
      ...
      {
        test: /\.scss/,
        use: [{
          loader: "style-loader"
        }, {
          loader: "css-loader", options: {
            sourceMap: true
          }
        }, {
          loader: "sass-loader", options: {
            sourceMap: true,
            data: '@import "variables";',
            includePaths: [
              path.join(__dirname, 'src')
            ]
          }
        }],
        include: path.join(__dirname, 'src')
      }
    ]

@intermundos
Copy link

@eegl your solution works for me. Thank you.

@laurazenc
Copy link

@lorenzomigliorero's solution worked for me, except I had to go up one level to access the style folder which was inside the src folder

@import '${path.resolve(__dirname, '..', 'src', 'style').replace(/\\/g, '/')}/vars';

@davidfurlong
Copy link

davidfurlong commented Sep 22, 2017

If my variables.scss is in src/styles/variables.scss how can I modify @eegl 's solution to get it to work? Appreciate the help, webpack debugging is tough.. Additionally does that solution mean I still need to do an import '~variables'; in my local scss files?

@th3fallen
Copy link

th3fallen commented Oct 19, 2017

First of all thanks so much @eegl, but has anyone found a way to do this that allows your variables or mixins you're adding to have access to native sass functions i.e. darken

or for the variable's to use a var defined int he same file, something like

$color: #fff;
label {
   color: darken($color, 15%);
}

@intermundos
Copy link

With EEGL's solution I got variables, mixins and function work as needed.

Just add data property to sass loader and specify path of the main sass config file. This way I get sass working with all of its functions.

After that there is no need to import variables file in local was files.

@th3fallen
Copy link

derp i was missing a func that was being called to get the color

@lukaszkups
Copy link

@eegl and @natchiketa solutions works for me, but in the end won't they produce huge css repetitive code? (or maybe not - I'm not sure, that's why ask - just curious about it)

@eeglbalazs
Copy link

eeglbalazs commented Feb 12, 2018

@mrmnmly if you put actual css rules into this globally imported scss file, you will end up with repetitive code. This solution only works properly for sass variables and mixins, b/c those won't directly appear in the final CSS.

@lukaszkups
Copy link

@eegl thank You for the clarification

@ghost
Copy link

ghost commented Feb 25, 2018

My webpack version is version 3.7.x. I met the same problem, and I tried all the solution mentioned above, but the problem still not solved

@intermund
Copy link

intermund commented Mar 14, 2018

Just in case, here is my webpack dev config part for SASS

                        {
                            loader: 'sass-loader',
                            options: {
                                outputStyle: 'expanded',
                                sourceMap: false,
                                data: '@import "../src/styles/config/scss";',
                                includePaths: [ PATHS.src.root ]
                            }
                       }

@lanzhiheng
Copy link

https://github.com/webpack-contrib/sass-loader#environment-variables This link can help you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests