Responsive Advertisement

SASS/SCSS #3: Why we should use @use, @forward instead of @import

 

Welcome to the new article on SASS/SCSS. If you are interested in this topic, here is the link for you to follow other articles in the series about SASS/SCSS. Series about SASS/SCSS.

In this article, I will talk about @import, @use, @forward and why we should replace @import with @use and @foward.

Table of contents:

  • How to use @import
  • How to use @use
  • @import vs @use
  • How to use @forward

Let’s go to the contents!

How to use @import

When you're just starting to learn about SASS/SCSS, the first thing you'll learn when concatenating two files is using @import. Let's see a simple example of how to use @import. We have a file “_variables.scss”.

// _variables.scss

$font-size: 16px;

$font-weight: 500;

$line-height: 1.5;

 

And the file “index.scss” uses @import to be able to use the values ​​in the file “_variables.scss”.

@import './variables';

 

body {

    font-size: $font-size;

    font-weight: $font-weight;

    line-height: $line-height;

}

 

The result that we get when we compile will be:

/* index.css */

body {

  font-size: 16px;

  font-weight: 500;

  line-height: 1.5;

}

 

This is what @import has been doing so far. However, when using @import people start to discover hidden bugs that can appear when using @import. Specifically, those reasons are:

·        @import makes all variables, mixins, and functions globally accessible. This makes it very difficult for people (or tools) to tell where anything is defined.

·        Because everything’s global, libraries must prefix to all their members to avoid naming collisions.

·        @extend rules are also global, which makes it difficult to predict which style rules will be extended.

·        Each stylesheet is executed and its CSS emitted every time it’s @imported, which increases compilation time and produces bloated output.

·        There was no way to define private members or placeholder selectors that were inaccessible to downstream stylesheets

The developer encouraged us to use @use instead so let's see how @use does.

How to use @use

First, you need to install to use @use in SASS/SCSS. Here are some steps for you to install:

npm install sass -b

 

Here is the syntax for you to install sass. After the installation is complete you will be able to install the node package. You would then use the following command:

sass --watch scss:css

 

“sass” is the command syntax, “—watch” is the flag that requires updating as soon as there is a change. “scss” is the folder containing the .SCSS files used to compile, and “css” is the folder to save the .css file of the result after the compilation is complete.

After doing the above steps we come to the uses of @use. Using the above problem again, we use @use to see how things will work?

// index.scss

@use "variables";

 

body {

    font-size: variables.$font-size;

    font-weight: variables.$font-weight;

    line-height: variables.$line-height;

}

 

And the result we get will be:

/* index.css */

body {

  font-size: 16px;

  font-weight: 500;

  line-height: 1.5;

}

 

First, we see that the syntax of @use is more complex than that of @import. We use the namespace, which is the name for the file, and from the namespace we get the variables. So, is there any way to make this job shorter? We will use alias, which means we will rename the namespace via a shorter name.

// index.scss

@use "variables" as v;

 

body {

    font-size: v.$font-size;

    font-weight: v.$font-weight;

    line-height: v.$line-height;

}

 

The syntax would be @use “_path” as short-name. That was shorter, but we still have a shorter way. Let's see!

// index.scss

@use "variables" as *;

 

body {

    font-size: $font-size;

    font-weight: $font-weight;

    line-height: $line-height;

}

 

 

So we have a way of calling variables just like we used @import. By using @use “_path” as *.

In another case, you only allow some of your variables defined to be used, the rest are unused. This means turning that variable from global to private. Let's go to the example we have a file "_variables.scss" as follows:

// _variables.scss

$-font-size: 16px;

$font-weight: 500;

$line-height: 1.5;

 

We will use @use to use the file “_variables.scss” in the file “index.scss” and compile:

// index.scss

@use "variables" as *;

 

body {

    font-size: $font-size;

    font-weight: $font-weight;

    line-height: $line-height;

}

 

The result we get will be:

/* Error: Undefined variable.

 *   ,

 * 5 |     font-size: $font-size;

 *   |                ^^^^^^^^^^

 *   '

 *   scss\index.scss 5:16  root stylesheet */

 

You see the unexpected happened the variable “$font-size” is completely unusable in the file using @use. The variable “$font-size” is made private by adding a “-” sign between “$” and “variable name”, which means that only the file “_variables.scss” can use this variable. Later, when you want any variables to be private, you can absolutely use this method.

@import vs @use

If you find that @use is more complicated to use than @import, here are some ideas to change your mind.

First if you use @import then all variables, mixins, functions in that file are loaded into the same file. As for @use, only variables, mixins, and functions that are called will be loaded and the rest are not. So, if we consider the processing bandwidth for sass files. We see that if we use too much @import, the processing bandwidth will be more. When entering a large project, the greater the number of files using @import, the higher the risk of unexpected errors.

On the other hand, if we use @use, the variables, functions, and mixins we use will be loaded. Thus, we have saved bandwidth, processing performance will be much higher.

Next, we have @import make all variables, mixin, functions, … can access globally. If you are an experienced developer, then placing variables and functions in the global scope is extremely dangerous. In case your program is on a small scale there is nothing to talk about. If in a large scale, the project has up to dozens of files to manage, the naming of variables and functions can completely be duplicated and lead to overriding. Make your system vulnerable to bugs anywhere.

Let's see how globally is @import? We have a file “_color.scss” as follows:

// _color.scss

$primary-clr: #343434;

$seconday-clr: #898989;

 

We will use @import in the file “_variables.scss”.

// _variables.scss

@import 'color';

$font-size: 16px;

$font-weight: 500;

$line-height: 1.5;

 

Can we use the variable in the file “_color.scss” in the file “index.scss” or not.

// index.scss

@import 'variables';

 

body {

    background-color: $primary-clr;

    font-size: $font-size;

    font-weight: $font-weight;

    line-height: $line-height;

}

 

The result will be:

/* index.css */

body {

  background-color: #343434;

  font-size: 16px;

  font-weight: 500;

  line-height: 1.5;

}

 

Completely usable. Along with the above problem, we use @use in the file “_variables.scss” then everything will be like?

// _variables.scss

@use 'color' as *;

$font-size: 16px;

$font-weight: 500;

$line-height: 1.5;

 

In the file “index.scss” will use the same:

// index.scss

@import 'variables';

 

body {

    background-color: $primary-clr;

    font-size: $font-size;

    font-weight: $font-weight;

    line-height: $line-height;

}

 

The results we get:

/* index.css */

/* Error: Undefined variable.

 *   ,

 * 5 |     background-color: $primary-clr;

 *   |                       ^^^^^^^^^^^^

 *   '

 *   scss\index.scss 5:23  root stylesheet */

 

 

Thus, we can confirm again that only when we use @use in a file, that file can use variables.

You can see the outstanding points that @use brings when we use it. At the same time, we can reduce the number of unwanted bugs that we may encounter. There is a point that you will wonder if in the case that we want to use variables, mixins, functions in many files like @import is it possible or not. The answer is yes, let's go to the theory of @foward.

How to use @forward

You've seen the restriction where @use is when you want to use it outside of files that use @use. To overcome this we use @foward. So, let's see how @foward uses it. We have the file “_color.scss” as follows:

// _color.scss

$primary-clr: #343434;

$seconday-clr: #898989;

 

And the file “_variables.scss” will use @foward for the file “_color.scss”.

// _variables.scss

@forward 'color';

$font-size: 16px;

$font-weight: 500;

$line-height: 1.5;

 

And we use @use for the file “_variables.scss” in the file “index.scss”.

// index.scss

@use 'variables' as *;

 

body {

    background-color: $primary-clr;

    font-size: $font-size;

    font-weight: $font-weight;

    line-height: $line-height;

}

 

 

The result we get will be:

/* index.css */

body {

  background-color: #343434;

  font-size: 16px;

  font-weight: 500;

  line-height: 1.5;

}

 

You'll find it a bit more complicated than using @import. As mentioned above, using @import contains too many risks leading to unexpected bugs and making the work of handling files heavier because it has to load the entire imported file. While we can reduce the risk of bugs, we increase productivity by using @use, @forward. So, what do you think with the above trade-off? Please comment your opinion below.

Conclusion

We have gone through how to use @import, @use, @forward. We've got an overview of why we should replace @import with @use and @forward.

If you have any ideas, feel free to comment below. Thank you for joining with me. Having a good day!


Đăng nhận xét

0 Nhận xét