scss - Usage of '~' in imports is deprecated - angular - vscode
Asked Answered
B

2

40

Since angular 13, using a tilde (~) to import SCSS files from the node_modules

close.component.scss

:host ::ng-deep {
    // Configuration
    @import "~bootstrap/scss/functions";
    @import "~bootstrap/scss/variables";
    @import "~bootstrap/scss/mixins";

    // Layout & components
    @import "~bootstrap/scss/close";
}

results in the following warning after running ng build:

Warning: 'C:\repos\...\src\lib\components\close\close.component.scss' imports '~bootstrap/scss/close' with a tilde. Usage of '~' in imports is deprecated.

Changing this and removing the tilde is easy. But VS Code doesn't find the file anymore when ctrl clicking the scss-path. It thinks it's located at

C:\repos\...\src\lib\components\close\bootstrap\scss\close

I've already tried this change but it changes nothing.

Does anyone know how to fix this?

Edit

For those wondering why we need :host ::ng-deep around the @import statements, it scopes the styles within to the component. A good example here is the bs-list-group and bs-list-group-item which I use like this:

<bs-list-group>
    <bs-list-group-item>Cras justo odio</bs-list-group-item>
    <bs-list-group-item>Dapibus ac facilisis in</bs-list-group-item>
    <bs-list-group-item>Morbi leo risus</bs-list-group-item>
    <bs-list-group-item>Porta ac consectetur ac</bs-list-group-item>
    <bs-list-group-item>Vestibulum at eros</bs-list-group-item>
</bs-list-group>

The following scss imports in list-group.component.scss

// Configuration
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";

// Layout & components
@import "~bootstrap/scss/list-group";

Result in the following

Bootstrap listview with scoped styles

On the other hand:

:host ::ng-deep {
    // Configuration
    @import "~bootstrap/scss/functions";
    @import "~bootstrap/scss/variables";
    @import "~bootstrap/scss/mixins";

    // Layout & components
    @import "~bootstrap/scss/list-group";
}

Where ng-deep removes the component scopes, and :host is replaced with the attribute angular applies on the BsListViewComponent (in this case [_nghost-bkg-c64]). This lets the styles work for the entire BsListviewComponent, since the scopes were removed from the css selectors.

Bootstrap listview with stripped scopes

This actually DOES work...

Bayonne answered 26/9, 2022 at 11:54 Comment(5)
Why are your imports in a selector ?Leeway
Because I'm using angular, this scss file is for a component and thus angular scopes these styles to the component. .example would become *[_ngcontent-wcc-c60] .example after the build. Adding ::ng-deep removes these scopes right-hand side of it. This way, I'm able to make the bootstrap styles flow over multiple cooperating angular componentsBayonne
But angular material seems to do this totally different...Bayonne
This is wrong. Imports go to the head of the file, NOT inside the selectors.Aftershaft
@E.Maggini is right, and you're wrong about this scss file is for a component and thus angular scopes these styles to the component : imports are juste imports, they do not add content to your CSS file (it's @include that does that). Imports should go at the top of your code. Not that it resolves your issue, but I wanted to point it out ...Leeway
H
10

You have to replace with the path to the css, something like:

@import 'node_modules/bootstrap/scss/mixins'

Before doing that, I recommend going to the bootstrap file that you want to import and get the relative path to the file.

The in your scss file replace the ~ path with the relative path.

Be careful to not include .scss file inside the path.

Hexamerous answered 26/9, 2022 at 12:45 Comment(1)
Thanks for the reply. This compiles fine too, but it still doesn't allow me to ctrl+click the paths (@import "node_modules/bootstrap/scss/functions";)Bayonne
T
50
  1. In angular.json file

  2. Add this below build -> options:

"stylePreprocessorOptions": {
   // other options...
   "includePaths": [
     "./node_modules"
   ]
 }  
  1. Remove ~ in every import

Take this warning with a grain of salt: It might be better to explicitly use the node_modules/ prefix instead, especially if more than one person is working on this project.

Tiebold answered 14/10, 2022 at 2:39 Comment(6)
In my project I did not already have a stylePreprocessorOptions setting and I did not understand where to put it. After looking a bit, this should go into build -> options section, in my case I put it directly under the "styles" entry.Weiser
Yes, it should directly go under build > options. Reference: angular.io/guide/workspace-config#style-preprocessor-optionsUcayali
If you don't want to add all node modules, you can add individual paths, e.g. for ~swiper/scss, ~swiper/scss/autoplay, etc., just remove "./node_modules" and add "./node_modules/swiper". Add an entry for each package you want to include.Furnishing
when I do this (after removing the tilde from @import '~@angular/material/theming';), I get "Cannot find mixin 'mat-elevation'" on a line like this: @include mat-elevation(8);Cowpuncher
This still doesn't allow me to ctrl+click on the pathBayonne
@CeeMcSharpface maybe it should be @include mat.elevation(8);Semilunar
H
10

You have to replace with the path to the css, something like:

@import 'node_modules/bootstrap/scss/mixins'

Before doing that, I recommend going to the bootstrap file that you want to import and get the relative path to the file.

The in your scss file replace the ~ path with the relative path.

Be careful to not include .scss file inside the path.

Hexamerous answered 26/9, 2022 at 12:45 Comment(1)
Thanks for the reply. This compiles fine too, but it still doesn't allow me to ctrl+click the paths (@import "node_modules/bootstrap/scss/functions";)Bayonne

© 2022 - 2024 — McMap. All rights reserved.