Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Export SASS/SCSS variables to Javascript without exporting them to CSS

Tags:

Background

Consider the following _variables.scss file:

/* Define all colours */
$white:    #fff;
$black:    #000;
$grey:     #ccc;
// etc...

// Export the color palette to make it accessible to JS
:export {
    white: $white;
    black: $black;
    grey: $grey;
    // etc...
}

The purpose of the above code is to make the SCSS variables available to Javascript by means of importing like so:

import variables from 'variables.scss';

See a more detailed description here.

The Problem

Now consider the following template (I have used as Vue.js template as an example but this is relevant to numerous frameworks):

<!-- Template here... -->

<style lang="scss" scoped>

    // Import Partials
    @import "~core-styles/brand/_variables.scss";
    @import "~core-styles/brand/_mixins.scss";

    // Styles here...

</style>

In the above example I have used the scoped attribute as this demonstrates the worst case scenario for the upcoming problem, but even without scoped the problem is still relevant.

The above SCSS will compile to something along the lines of:

[data-v-9a6487c0]:export {
    white: #fff;
    black: #000;
    grey: #ccc;
    // etc...
}

In addition, with the scoped attribute, this will repeat every time _variables.scss is imported into a template, and can potentially result in additional redundant code. In some cases, for large applications (many components and a large colour palette), this can literally add 000's of lines of completely redundant code.

My Question

Is there a way to export the SCSS variables to Javascript without exporting them to CSS?

Potential (dirty) Solution

I am ideally trying to avoid a solution of having a separate file named, for example, _export.scss where its purpose is simply to export all SCSS variables to JS, but it is excluded from all CSS builds...

Just to expand on the above dirty solution, this is what I am currently resorting to (in my case, on a standard size website, it has so far saved me ~600 lines of redundant CSS code):

_export.scss

/*
 |--------------------------------------------------------------------------
 | SASS Export
 |--------------------------------------------------------------------------
 |
 | Define any variables that should be exported to Javascript. This file
 | is excluded from the CSS builds in order to prevent the variables from
 | being exported to CSS.
 |
 */

@import "variables";

:export {

    // Export the color palette to make it accessible to JS
    white: #fff;
    black: #000;
    grey: #ccc;
    // etc...

}

Then, in my Javascript instead of importing from _variables.scss, I import from _export.scss like so:

import styles from 'core-styles/brand/_export.scss';

And finally, the export statement, can now be removed from the _variables.scss file, thus preventing the compiled CSS export code.

Note: The _export.scss file must be excluded from the SCSS compilation!

like image 355
Ben Carey Avatar asked Aug 17 '19 12:08

Ben Carey


People also ask

Can you use SCSS variables in JS?

To make Sass (or, specifically, SCSS in this case) variables available to JavaScript, we need to “export” them. The :export block is the magic sauce webpack uses to import the variables. What is nice about this approach is that we can rename the variables using camelCase syntax and choose what we expose.

Can I use SCSS instead of CSS?

SCSS contains all the features of CSS and contains more features that are not present in CSS which makes it a good choice for developers to use it. SCSS is full of advanced features. SCSS offers variables, you can shorten your code by using variables. It is a great advantage over conventional CSS.

Can SCSS variable change dynamically?

SCSS is compiled to CSS during compile time, and SCSS variables are replaced with resolved value during compile time, which means there is no way to change the variable during run time. However, CSS variables just sits there during run time, and you can dynamically CRUD them during run time with JavaScript (Web API).

How do you globally access Sass SCSS variables in react?

Each import of SCSS file in JS file is treated as an isolated SASS env, therefore, there is no such thing "global variables" while using SCSS in React. This behavior requires us to import the variables. scss file into each SCSS file that uses one of the variables. @import "variables.


1 Answers

Note: I have posted this answer because it seems there is no better solution, however, if someone subsequently provides a better solution, I will be more than happy to accept it.

It seems that the only real solution to this is to extract the export statement out of the _variables.scss file and place it into its own _export.scss file which will subsequently not be included in the SCSS compliation.

This will look something like this:

_variables.scss - included in the SCSS compilation

/* Define all colours */
$white:    #fff;
$black:    #000;
$grey:     #ccc;
// etc...

_export.scss - not included in the SCSS compilation

@import "variables";

:export {

    // Export the color palette to make it accessible to JS
    white: #fff;
    black: #000;
    grey: #ccc;
    // etc...

}

And then your app.scss (I use brand.scss) file will look something like this (note the absence of @include "export";):

@import "variables";
@import "mixins";
@import "core";
@import "animations";
// etc...

Then, _export.scss is simply referenced only in JavaScript like so (note that core-styles is just an alias that I used in my projects):

import styles from 'core-styles/brand/_export.scss';
like image 189
Ben Carey Avatar answered Sep 17 '22 14:09

Ben Carey