Git Product home page Git Product logo

Comments (56)

kasper573 avatar kasper573 commented on May 20, 2024 25

Hi! I wanted the same feature a while back but realized this is already supported by webpack. My solution looks like this:

var sass = encodeURIComponent(jsonToSassVars(sassGlobals));
var webpackConfig = {
    module: {
        loaders:[
            {test: /.scss$/, loader: "style!css!sass!prepend?data=" + sass}
        ]
    },
}

The prepend-loader and jsonToSassVars are custom work of mine.

from sass-loader.

mwilc0x avatar mwilc0x commented on May 20, 2024 12

@jhnns I can get the environment variable to be passed in via data-option and I see that it is working in the app.

I am doing something like:

sassLoader: {
  data: '$myColor: green;',
},

and then in a random .scss file I just use color: $myColor. It works, I can see the color appearing in the application, but I am also seeing errors at compile time: Undefined variable: "$myColor". Is there a step that I am missing here to complete this so as to not get those errors?

from sass-loader.

nwhite89 avatar nwhite89 commented on May 20, 2024 11

@jhnns thank you for your response I'm thinking of the webpack.DefinePlugin so perhaps something like

webpack.DefinePlugin({
  'SCSS_OPACITY': '0.4'
});
$opacity: SCSS_OPACITY;
@include opacity($opacity);

but perhaps if it's easier for it to create a file with all of them and somehow matching SCSS_OPACITY to be $SCSS_OPACITY ?? and attaching the variables above of files when generating? what are your thoughts?

from sass-loader.

CodePlayer7 avatar CodePlayer7 commented on May 20, 2024 6

@volodymyr-tsaryk check above @jhnns answers. For simple varibles you may do sth like this

{
    loader: "sass-loader",
    options: {
        data: "$var1: " + yourVar1+ ";"
    }
}

from sass-loader.

scott-thrillist avatar scott-thrillist commented on May 20, 2024 4

So useful, glad Google led me here. Thanks all.

https://webpack.js.org/loaders/sass-loader/#environment-variables

from sass-loader.

EdwardIrby avatar EdwardIrby commented on May 20, 2024 3

@kasu really liked your work so I went and forked it into a npm loader https://www.npmjs.com/package/jsontosass-loader

from sass-loader.

epegzz avatar epegzz commented on May 20, 2024 3

How is that easier than passing the vars directly in webpack config or by specifying paths to JS/JSON files?
https://github.com/epegzz/sass-vars-loader does support exactly that:

// webpack.js
sassVars: {
  vars: {
    someColor: red,
    someOtherColor: blue,
   }
 }

…and you're ready to use them anywhere in your scss

.foo {
  color: $someColor;
}

from sass-loader.

JasonEtco avatar JasonEtco commented on May 20, 2024 3

I think it's worth noting that @jhnns above solution is great, but the description on how to actually use it wasn't clear. The sassLoader object has to be in the root of your webpack's exported object, like this:

module.exports = {
  entry: [...],
  module: {
    loaders: [...],
  },
  sassLoader: {
    data: '@import "variables";',
    includePaths: [
      path.resolve(__dirname, '../src/scss/tools'),
    ],
  },
};

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024 2

Thx @nightgrey

This issue can now also be solved with the data-option. Just define any Sass code which will be prepended to the actual entry file.

from sass-loader.

epegzz avatar epegzz commented on May 20, 2024 2

@IAMtheIAM haven't tested yet, but no, probably not then, thx for pointing it out! :)

The following should work with webpack2 though, right?

// webpack.js
var sassVarsConfig = querystring.stringify({
    files: [
        path.resolve(__dirname, 'path/to/vars.js'),
    ]
});

return {
    loader: ExtractTextPlugin.extract(
        'style',
        'css!sass!@epegzz/sass-vars-loader?' + sassVarsConfig
    ),
  //...

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024 2

When they're using !default, yes. Otherwise, no.

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024 2

While this is true for webpack 1, this has been changed with webpack 2. See current README.

from sass-loader.

kasper573 avatar kasper573 commented on May 20, 2024 1

@nwhite89 Sure thing, here you go: prependLoader.js and jsonToSassVars.js.

from sass-loader.

kasper573 avatar kasper573 commented on May 20, 2024 1

@EdwardIrby cool :)!

from sass-loader.

epegzz avatar epegzz commented on May 20, 2024 1

Hey guys, had the same needs for passing vars to my sass files, so i also created a little webpack loader based on @kasu's gist. It lets you import vars directly via webpack, or by specifying a JSON or JS file. Check it out :)

from sass-loader.

Cleod9 avatar Cleod9 commented on May 20, 2024 1

@epegzz This way you can basically just write Sass rather than JS. Also by prepending as a string you could theoretically just use fs to prepend a full .scss file if you wanted. To give you some context, the earlier answer of prepend-loader sufficed for me for a time, but broke after I had switched from ExtractTextPlugin to style-loader

from sass-loader.

epegzz avatar epegzz commented on May 20, 2024 1

@Cleod9 writing JS or JSON inside the webpack config which is JS itself feels way nicer to me. And the OP wanted to pass data potentially stored in a database. Chances are, those data already come as JSON or even JS object when he's loading them inside the webpack.js. But in the end, it's all a matter of personal preference and specific use case :)

from sass-loader.

CodePlayer7 avatar CodePlayer7 commented on May 20, 2024 1

With using "sass-loader": "4.0.2","webpack": "^1.13.2",, it comes to me that the environment variable function doesn't work.Compiling throws error Undefined variable

from sass-loader.

subvertallchris avatar subvertallchris commented on May 20, 2024 1

Anyone trying to use simple variables as described by above, the data key appears to have been changed to prependData. You'd now do this:

{
    loader: "sass-loader",
    options: {
        prependData: "$var1: " + yourVar1+ ";"
    }
}

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024

Could you show an example how you'd expect things to work?

I'm afraid that this is currently not possible (if I got it right). But with custom importers #31 it's probably possible. Then you can write a special loader, which generates scss code to import your dynamic vars.

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024

Mhmmm your solution would probably work too.

And when you need to access the variables also via client-side JavaScript:

webpack.DefinePlugin(require("./styles/variables.js"));

from sass-loader.

nwhite89 avatar nwhite89 commented on May 20, 2024

Yeah, using the definePlugin I think would be ideal because it would use the current inner workings of webpack but also allow for variables to be used across both the JS and SCSS files which I'm not entirely sure when you may need it but it would be more powerful I feel.

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024

Oh, there are use-cases where this is required... :)

I'll check that!

from sass-loader.

nwhite89 avatar nwhite89 commented on May 20, 2024

Using this perhaps? https://github.com/webpack/docs/wiki/list-of-plugins#dependency-injection

Without looking into it I would hazard a guess it should make it easier? (hopefully) :)

from sass-loader.

nwhite89 avatar nwhite89 commented on May 20, 2024

@kasu any chance of them being made Open Source?

from sass-loader.

nwhite89 avatar nwhite89 commented on May 20, 2024

@kasu cheers πŸ‘ although it would be nice to have this functionality baked into sass-loader

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024

@kasu haha, nice!
@nwhite89 no I don't think so. I don't want to extend the language itself...

from sass-loader.

nwhite89 avatar nwhite89 commented on May 20, 2024

@EdwardIrby πŸ‘

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024

Is @EdwardIrby 's solution working for you? I'd like to link the loader in our README, but I'm not sure about how safe that string replaces are 😁 ...

Do you have any experience on this?

from sass-loader.

wendellmva avatar wendellmva commented on May 20, 2024

@EdwardIrby I don't think you should return a json file but a js file that returns an json object. This way you can do custom calculations to darken or lighten a color for example or other caculations you might need.

from sass-loader.

nightgrey avatar nightgrey commented on May 20, 2024

@nwhite89 @EdwardIrby @jhnns I think this could be what you guys need: Sassport

I just found this myself and didn't use it yet, but it seems like it enables you to do what you want - sharing values between JavaScript and Sass.

from sass-loader.

matt-newell avatar matt-newell commented on May 20, 2024

@jhnns can we see a working example of the data option? Having issues getting it to work

Never mind looking back at earlier PR's I found my query params were overriding my sassLoader. It's a bit confusing where to options, query params or sassLoader

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024

It's a bit confusing where to options, query params or sassLoader

I know... this will be simpler with webpack 2 where there is a dedicated way to set the options (query params didn't work so well with more complex use-cases).

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024

Nope, looks good. There must be a different error in your setup.

from sass-loader.

mwilc0x avatar mwilc0x commented on May 20, 2024

@jhnns Yeah, the issue was that I wasn't including this option on the server bundle as well. It is working, thanks!

from sass-loader.

Cleod9 avatar Cleod9 commented on May 20, 2024

After much digging around, I found an even easier solution:

https://www.npmjs.com/package/webpack-append

Despite its misleading name, this package does, in fact, prepend specified text to the beginning of each file. And unlike prepend-loader, it doesn't have any issues with style-loader πŸ˜„

from sass-loader.

Cleod9 avatar Cleod9 commented on May 20, 2024

@epegzz True, and I appreciate your plugin btw! I think for others who land in this thread will find that at least one of these solutions will work for them (this thread is like the number one search result for "sass variables through webpack" πŸ˜‰ )

from sass-loader.

IAMtheIAM avatar IAMtheIAM commented on May 20, 2024

@epegzz is it webpack2 compatible? Webpack2 doesn't allow custom properties on the webpack config, must use the LoaderOptionsPlugin for any custom properties.

from sass-loader.

IAMtheIAM avatar IAMtheIAM commented on May 20, 2024

@epegzz Good job dude! That worked perfectly, thanks, I was struggling for hours to get any of these options to work with webpack 2, so that I can take a JS/JSON file and have it converted to sass, and appended before all scss files. Great!

Here's my full setup:

// webpack.config.js

var sassVarsConfig = querystring.stringify({
   files: [
      path.resolve(helpers.paths.appRoot + '/assets/styles/sass-js-variables.js'),
   ]
});

// loaders section
         {
            test: /\.(scss)$/,
            loaders: DEBUG ?
               ['style', 'css?sourceMap', 'postcss', 'sass?sourceMap', 'sass-resources', '@epegzz/sass-vars-loader?' + sassVarsConfig] : // dev mode
               ExtractTextPlugin.extract({
                  fallbackLoader: "sass-loader",
                  notExtractLoader: "sass-loader",
                  loader: ['css?sourceMap', 'postcss', 'sass?sourceMap', 'sass-resources','@epegzz/sass-vars-loader?' + sassVarsConfig],
                  publicPath: '/' // 'string' override the publicPath setting for this loader
               })
         },

//plugins section

      new webpack.LoaderOptionsPlugin({
         options: {
            sassResources: ['./src/assets/styles/variables.scss', './src/assets/styles/mixins.scss'],
            context: helpers.paths.root
         }
      }),

      new ExtractTextPlugin({
         filename: '/css/[name].style.css?[hash]',
         disable: false,
         allChunks: true
      }),
// sass-js-variables.js

module.exports = {
   primary: '#C0FF33',
   secondary: '#B4D455'
};
// home.scss

ticket {
   color: $primary;
   .card-panel {
      background-color: $secondary;
   }
}

Now the only thing I'm wondering is it your sass-vars-loader can replace the functionality of the sass-resources-loader? Basically it just appends an array of .scss files to the beginning of each .scss file loaded, which I use for passing all my variables and mixins to my scss files. Can your loader do that, and if so, what's the proper way? It's not a big deal, since it works as is, I can use 2 loaders if necessary.

from sass-loader.

IAMtheIAM avatar IAMtheIAM commented on May 20, 2024

@epegzz I made a pull request fixing your loader, to allow users to pass "vars" directly on the webpack config, rather than in an external file. So now both options work. Please review and approve it so others can use :-)

You just have to JSON.stringify anything in the vars property like this:

const susyDebug = DEBUG ? 'show' : 'hide';
const sassVarsConfig = querystring.stringify({
   files: [
      path.resolve(helpers.paths.appRoot + '/styles/sass-js-variables.js')
      // path.resolve(__dirname, '/path/to/breakpoints.js'), // JS
      // path.resolve(__dirname, '/path/to/colors.json'), // JSON
   ],
   vars: [JSON.stringify({'susyDebug': susyDebug})],
});

Then, your loader should look something like:

loaders: ['css?sourceMap', 'postcss', 'sass?sourceMap', '@epegzz/sass-vars-loader?' + sassVarsConfig],

from sass-loader.

epegzz avatar epegzz commented on May 20, 2024

awesome @IAMtheIAM, merged and pushed to npm :)

from sass-loader.

534N avatar 534N commented on May 20, 2024

@epegzz I can't install your module:

npm ERR! Invalid name: "@epegzz/sass-vars-loader"

from sass-loader.

epegzz avatar epegzz commented on May 20, 2024

@534N I answered in epegzz/sass-vars-loader#6 :)

from sass-loader.

nagarajay avatar nagarajay commented on May 20, 2024

@jhnns Is the data option working correctly for Webpack V2. @epegzz @IAMtheIAM great solution. I will try to use it as stated.

from sass-loader.

jhnns avatar jhnns commented on May 20, 2024

@nagarajay Does this work for you?

from sass-loader.

mkarajohn avatar mkarajohn commented on May 20, 2024

I understand that the solutions above allow us to define and use SASS variables in our sass files without actually touching them, but how about overriding existing variables?

For example, could we override the $enable-flex variable of Bootstrap 4 from false to true in order to build the flexbox version of the grid ?

from sass-loader.

volodymyr-tsaryk avatar volodymyr-tsaryk commented on May 20, 2024

@CallMeXYZ did you resolve your issue ? I am having same

from sass-loader.

volodymyr-tsaryk avatar volodymyr-tsaryk commented on May 20, 2024

@CallMeXYZ that worked, thanks

from sass-loader.

scorgn avatar scorgn commented on May 20, 2024

@epegzz Your solution is great, although I'm wondering if there's a way to use it when requiring scss files. I think that it would make more sense to be able to specify the variables in your index.js file.

The reason I want to do this is I would like to be able to set background-images dynamically. Something like

var headerBackgroundImage = require(htmlWebpackPlguin.options.bgImage);
require('style.scss')({
    '$header-background': headerBackgroundImage
});

from sass-loader.

epegzz avatar epegzz commented on May 20, 2024

@ShawnCorrigan although I can see use-cases for your proposal, it, unfortunately, does not play well with ES6 modules :(

from sass-loader.

epegzz avatar epegzz commented on May 20, 2024

@ShawnCorrigan However, you could simply call require(htmlWebpackPlguin.options.bgImage) in your webpack config file:

// webpack.config.js

const headerBackgroundImage = require(htmlWebpackPlguin.options.bgImage);

module.exports = {
  module: {
    rules: [{
      test: /\.scss$/,
      use: [
        // …
        { 
          loader: "@epegzz/sass-vars-loader",
          options: {
            vars: {
              'header-background': headerBackgroundImage
            }
          }
        }
      ]
    }]
  },
};

from sass-loader.

scorgn avatar scorgn commented on May 20, 2024

@epegzz Hmm okay. The idea was to not really modify the webpack.config.js file, although I suppose I could have another file that the webpack.config.js file uses to load the images. Thanks for the response!

from sass-loader.

epegzz avatar epegzz commented on May 20, 2024

@ShawnCorrigan Sorry for the late reply, I somehow missed your response above.

But yeah, you're absolutely right. In most cases, you probably want to load all vars from a file and never touch the Webpack config again :)

from sass-loader.

BruneXX avatar BruneXX commented on May 20, 2024

Hi @volodymyr-tsaryk with one var works like a charm, but how to share multiple vars? is that possible? thanks!

from sass-loader.

devtas avatar devtas commented on May 20, 2024

@kasu really liked your work so I went and forked it into a npm loader https://www.npmjs.com/package/jsontosass-loader

This guy no longer supports this lib. Sad.

from sass-loader.

boltgolt avatar boltgolt commented on May 20, 2024

If you're here through a google search, this has been renamed once more to additionalData, so:

{
	loader: "sass-loader",
	options: {
		additionalData: '$myColor: green;'
	}
}

See #865

from sass-loader.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.