Skip to content

Property: injectGlobalPaths doesn't take into account @use rules #70

@lennu

Description

@lennu

Lets say I have the following setup:

{
  injectGlobalPaths: ['./mixins.scss']
}
### mixins.scss
@mixin whatever {
  margin: 0;
}
### styles.scss
use "sass:math";

div {
  width: math.div(100, 2);
}

This will end up with error: @use rules must be written before any other rules.
https://sass-lang.com/documentation/at-rules/use

The code which adds the import statements, should analyze the file and add import clauses under @use statements instead of just adding them to beginning of the each file.
https://github.com/ionic-team/stencil-sass/blob/7871073e3a882af4bf9a8fc7bf4faf6092828ee4/src/util.ts#L55

Activity

andrejpavlovic

andrejpavlovic commented on Nov 18, 2021

@andrejpavlovic

As a workaround I removed the use of injectGlobalPaths and now import global scss files (such as mixins.scss) directly inside of component styles (such as styles.scss).

A143447

A143447 commented on Nov 29, 2021

@A143447

Our workaround was to create a workaround-scss file that performs the calculations, assigning them to variables and importing that file in the mixins.scss. It's a bit of a hack, we only had seven instances where that calculation was needed (as opposed to many more .scss files)

r3dDoX

r3dDoX commented on Jan 28, 2022

@r3dDoX

Just ran in the same issue. Since we have quite a big project these workarounds are not a good option for us. Is anyone working on this?

nickjwilde

nickjwilde commented on Oct 7, 2022

@nickjwilde

We had this same issue as well. Looking into @lennu reference to https://github.com/ionic-team/stencil-sass/blob/7871073e3a882af4bf9a8fc7bf4faf6092828ee4/src/util.ts#L55

Switching that line to

return `@use "${injectGlobalPath}"${importTerminator}`;

Worked for me. However, this makes injected global paths use a namespace, so

'src/global/colors.scss'

Ends up with a colors namespace as per docs https://sass-lang.com/documentation/at-rules/use#choosing-a-namespace

Using

return `@use "${injectGlobalPath}" as *${importTerminator}`;

Removes the namespace if that's needed to make updating easier/more seamless.

I'd be happy to help with this issue.

Edits: formatting

mm-georges

mm-georges commented on Mar 13, 2025

@mm-georges

@christian-bromann I can contribute with a fix for that. I would go with the same approach as @nickjwilde mentioned by changing the line to return "@use "${injectGlobalPath}" as *${importTerminator}";

xofromthemoon

xofromthemoon commented on Apr 10, 2025

@xofromthemoon
Contributor
janina-bro

janina-bro commented on Apr 25, 2025

@janina-bro

I ran into a similar problem regarding injectGlobalPaths and @use .
Using the injectGlobalPaths option in stencil.config.ts makes the listed SCSS files available in every component. Since @import is deprecated, and this behavior was updated in version 3.2.1 of @stencil/sass, the plugin now uses @use instead.
However, @use behaves differently: it introduces namespaces, and its contents are not globally accessible unless explicitly referenced via a namespace. If the same namespace is used multiple times without a unique alias, it can lead to build errors in Stencil or Storybook.
Furthermore, even if SCSS files are included via injectGlobalPaths, they still need to be explicitly referenced using their namespace in each component’s stylesheet. See the following example structure:

# File structure
someComponents/
├── stencil.config.ts
├── src
│   └── components
│       └── button/
│           └── styles
│               ├── xy.project.scss
│               ├── xy.project.concept.scss
│               └── xy.project.common.scss
│           ├── button.stories.ts
│           ├── button.tsx
│           └── button.scss
│   └── utils
│       ├── constants.scss
│       ├── mixins.scss
│       └── utils.scss

/** stencil.config.ts */
import { Config } from '@stencil/core';
import { sass } from '@stencil/sass';
import { DEV_SERVER_PORT } from './stencil.constants';
import nodePolyfills from 'rollup-plugin-node-polyfills';

export const config: Config = {
  namespace: 'someComponents',
  devServer: {
    openBrowser: false,
    port: DEV_SERVER_PORT,
  },
  globalScript: 'src/utils/global.ts',
  globalStyle: 'src/utils/global.scss',
  taskQueue: 'async',
  outputTargets: [
    { type: 'dist' },
    { type: 'docs-readme' },
    {
        type: 'www',
        serviceWorker: null,
        buildDir: 'someComponents',
        copy: [
            { src: '../node_modules/@something/', dest: '../dist/someComponents/values/@something/', warn: true },
            { src: '../node_modules/@something/', dest: 'someComponents/values/@something/', warn: true },
            { src: 'components/app/worklets/', dest: 'someComponents/worklets/', warn: true },
            { src: 'example/', dest: 'example', warn: true },
            { src: 'example_*.html' },
        ],
    },
  ],
  plugins: [
    sass({
      injectGlobalPaths: [
        './src/utils/constants',
        './src/utils/utils',
        './src/utils/mixins',
    ],
    }),
    nodePolyfills(),
],
buildEs5: true,
};

/** xy.project.common.scss */
@use '../../../utils/mixins.scss' as mixins;

:host {
    display: block;
    position: relative;
    z-index: 0;
    margin: 0;
    padding: 0;
        .icon-slot {
        @include mixins.elevationLevel(4, 'light');
        }

    ...
}

/** xy.project.concept.scss */
:host-context([mode='xy.project.concept']) {
    button {
        &::after {
            // background
            background-color: rgb(var(--background-highlight));
            border: 1px solid rgb(var(--color));
        }
    }
}

/** xy.project.scss */
@use 'xy.project.common' as common;
@use 'xy.project.concept' as concept;

/** constants.scss */
$baseFontSize: 40px;
$headerHeight: 100px;

/** mixins.scss */
@mixin elevationLevel($level, $theme) {
    @if $level == 0 {
        box-shadow: none;
    } @else if $level == 0.5 {
        box-shadow: 0 5px 5px 0 rgba(0 0 0 / 7%);
        ...
    }
}

@mixin horizontal {
    position: absolute;
    left: 30%;
    transform: translateX(-50%);
}

/** utils.scss */
@use 'sass:math';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @christian-bromann@andrejpavlovic@r3dDoX@lennu@rwaskiewicz

        Issue actions

          Property: injectGlobalPaths doesn't take into account @use rules · Issue #70 · stenciljs/sass