Skip to content
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

Is it possible to include a global config/variables file? #211

Closed
joemckie opened this issue Jan 23, 2016 · 27 comments
Closed

Is it possible to include a global config/variables file? #211

joemckie opened this issue Jan 23, 2016 · 27 comments

Comments

@joemckie
Copy link

I've been looking through the docs and issues but I can't seem to find anything that quite encompasses this issue.

Take the following example in "standard" SASS:

@import "config";

@import "some-child-partial";

The child partial here would be able to access any variables exposed by the config file, but in sass-loader land, each stylesheet is treated as its own entity, meaning you can't do a global import.

Is there a way to include a file to all loaded stylesheets, or is it necessary to manually import the file in every stylesheet?

@mkoryak
Copy link

mkoryak commented Feb 8, 2016

you should look into node-sass options, specifically functions. if you dont mind specifying a function in js, then it will be globally available to all of your scss files.

@richard-flosi
Copy link

Previously i was getting global variables using the jsontosass-loader and the prepend-loader to make them available to all sass files. I just refactored to use the functions feature from node-sass so I could create a custom sass function to access my variables and was able to move my sass variables from json to js.

the gist:

const sass = require('node-sass');
const sassVars = require('./theme/vars.js');

// ...
  sassLoader: {
    functions: {
      'get($keys)': function(keys) {
        var keys = keys.getValue().split('.');
        var result = sassVars;
        var i;
        for (i = 0; i < keys.length; i++) {
          result = result[keys[i]];
        }
        return new sass.types.String(result);
      },
    },
  },
// ...

Then in my sass files I can access variables via get('colors.reports.blue'). Part of the motivation for this change was removing code like map-get(map-get($colors, reports), blue).

@mkoryak
Copy link

mkoryak commented Mar 21, 2016

@richard-flosi
you know that you dont need functions to do that, you could have implemented that exact thing as a sass function, though arguably with much more googling of syntax.
You should also return sass.types.Color there instead, otherwise you wont be able to use the result of that function in any function that requires a color

@richard-flosi
Copy link

Yeah, I'm not sure what that would look like as a sass function, but I did consider going that route in which case I would have had to use the prepend-loader to make that available to all sass files.
I was worried that returning sass.types.Color might be an issue, but using String for everything it working fine, colors, numbers, font families, etc.
Plus, it allows me to move my sass variables to js which I previously had in JSON so I could share them between sass and js.

@mkoryak
Copy link

mkoryak commented Mar 21, 2016

really? you can call darken and lighten on the strings returned from those functions?

@richard-flosi
Copy link

I'm not a sass expert, can you give me an example of the usage you are taking about and I'll test it out?

@mkoryak
Copy link

mkoryak commented Mar 21, 2016

sure in sass:

.poop {
   color: darken(get('colors.reports.blue'), 10%);
}

@richard-flosi
Copy link

yup, you are correct, that doesn't work with String type.

@wilfredjonathanjames
Copy link

Looking for a similar thing. Would love it if there were a way of defining global imports. For instance, I have this at the head of every sass file:

@import '../config/config';

Would be great to import it by default to every stylesheet.

@andrewmclagan
Copy link

andrewmclagan commented May 22, 2016

+ 1,000,000,000,000...

@jhnns
Copy link
Member

jhnns commented Jun 26, 2016

The child partial here would be able to access any variables exposed by the config file, but in sass-loader land, each stylesheet is treated as its own entity, meaning you can't do a global import.

This is not true. You can do global imports just like in regular sass. Please provide a minimal test example if you think this is a bug.

@bensampaio
Copy link

@jhnns could you show an example on how to do global imports then? I'm having this same issue. Thank you!

@mkoryak
Copy link

mkoryak commented Jul 11, 2016

the latest version of sass-loader finally lets you do this very easily. see #216

basically you need to pass the data option which should contain something like

@import '_my_global_stuffs.scss';

and put that file in an includePaths path so it can be found from anywhere.

inside of _my_global_stuffs.scss you can @import all the things you want to always be available

@jhnns
Copy link
Member

jhnns commented Jul 11, 2016

Yep.

However, I don't recommend this kind of project structure. In my experience, explicit dependencies are always better than implicit ones.

@mkoryak
Copy link

mkoryak commented Jul 11, 2016

even if every single scss file in your project is guaranteed to use some file you have to import?

I agree that you should keep the number of global things to a minimum, but its also silly to repeat yourself in every file of your project

@jhnns
Copy link
Member

jhnns commented Jul 11, 2016

but its also silly to repeat yourself in every file of your project

I don't think so. We all agreed that it's not good to use globals in JavaScript, why don't we adhere to the same principle in our stylesheets? It's a good thing to be explicit about the dependencies you are using. This way you always only import stuff that you are actual using.

@bensampaio
Copy link

I agree with you @jhnns. I would prefer if I could do this somewhere in my scss files. If I have to hide it in my webpack configuration then other developers won't know it is there and won't even consider looking there I guess. Thanks!

@Kikobeats
Copy link

apparently doesn't work in the last version, I don't know if a regression or what happens.

@shelldandy
Copy link

Yeah i'd like to know how to sort this out as well :) specially to have my mixins everywhere

@webdingens
Copy link

Using data and includePaths worked for me on sass-loader v. 4.1.1. While I do see the point of not using the global space there is also not enough time to make third party libraries conform to that idea. Unless there is a way to @import_once for production or otherwise prevent the style definitions from repeating themselves the idea of not using global variables at all doesn't seem feasible to me (bandwidth and time wise). But that might depend on the projects you are working on.

@evanjmg
Copy link

evanjmg commented Jan 10, 2017

anyone have a gist of their working code to share?

@vdefranc
Copy link

vdefranc commented Feb 2, 2017

As far as the discussion above about importing variables or mixins into every file, I'm finding that if I import a sass file in three different sass modules, webpack is bundling three copies of that imported file. Importing modules in this manner appears to me to be pretty detrimental.

Maybe there's something I'm missing.

@guillaumemolter
Copy link

A related discussion: vuejs/vue-loader#328

@jhnns
Copy link
Member

jhnns commented Feb 17, 2017

As far as the discussion above about importing variables or mixins into every file, I'm finding that if I import a sass file in three different sass modules, webpack is bundling three copies of that imported file. Importing modules in this manner appears to me to be pretty detrimental.

That's how Sass works by design. It's a compiler and every module is a distinct compilation. Usually, I split up my Sass modules in modules that are like libraries (they don't produce CSS code when imported) and modules that are like entry files. These are the Sass files that actually produce CSS code.

@thathurtabit
Copy link

I'm just trying to get my head around this.

So, if I have one file which includes my variables / mixins:
app/variables.scss

And then other components that have their own stylesheets which require the variables in app/variables.scss

So:

app/components/header.scss
app/components/page.scss
app/components/footer.scss
...

And they all need to reference and @import variables.scss... will all the variables be duplicated with each component when it reaches my compiled .css?

@alexander-akait
Copy link
Member

@thathurtabit yep, your should import variables/mixin/etc staff in each module, because it is module. To make it easier, you can create shared.scss (with variales, mixins, placeholders and etc) and include only one shared.scss file.

@alexander-akait
Copy link
Member

alexander-akait commented Jun 13, 2017

Two ways:

  1. Use common variables.scss file and include in every required file.
  2. Use https://github.com/shakacode/sass-resources-loader

Close. If these solutions do not suit your, please write here about this and explain why.

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