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 @import
ed, 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!
0 Nhận xét