Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCSS with :global and &:global directive not processed correctly #64299

Closed
tomitrescak opened this issue Apr 10, 2024 · 10 comments · Fixed by #68576
Closed

SCSS with :global and &:global directive not processed correctly #64299

tomitrescak opened this issue Apr 10, 2024 · 10 comments · Fixed by #68576
Assignees
Labels
bug Issue was opened via the bug report template. linear: turbopack Confirmed issue that is tracked by the Turbopack team. locked Turbopack Related to Turbopack with Next.js.

Comments

@tomitrescak
Copy link

tomitrescak commented Apr 10, 2024

Link to the code that reproduces this issue

https://github.com/tomitrescak/turbo-repro-scss

To Reproduce

Start the application in dev environment and see the screen

Current vs. Expected behavior

I would expect the nested styles to work correctly

<div className={`${styles.blue} green`}>
      Hello
      <div className="red">World</div>
</div>

And this is the style

.blue {
  background: blue;

  :global {
    .red {
      background: red;
    }
  }

  &:global {
    &.green {
      background: green;
    }
  }
}

(.blue.green) is not applied (stays blue and is not green)
(.red) is not applied (is green)

The default bundler processes everything correctly:

Running (next dev) works

image

Running (next dev --turbo) does not)

image

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:43 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 21.7.2
  npm: 10.5.0
  Yarn: 1.22.19
  pnpm: 8.15.6
Relevant Packages:
  next: 14.2.0-canary.64 // Latest available version is detected (14.2.0-canary.64).
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.1.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Turbopack (--turbo)

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

No response

PACK-2933

@tomitrescak tomitrescak added the bug Issue was opened via the bug report template. label Apr 10, 2024
@github-actions github-actions bot added the Turbopack Related to Turbopack with Next.js. label Apr 10, 2024
@tomitrescak
Copy link
Author

tomitrescak commented Apr 10, 2024

Looking at the source file it seems that turbo ignores the "global" directive. This is the file output.

/* [project]/app/page.module.scss.module.css [app-client] (css) */
.page-module-scss-module__qnDekq__blue {
  background: #00f;
}

.page-module-scss-module__qnDekq__blue :global .page-module-scss-module__qnDekq__red {
  background: red;
}

.page-module-scss-module__qnDekq__blue:global.page-module-scss-module__qnDekq__green {
  background: green;
}


/*# sourceMappingURL=app_page_module_scss_module_6ff146.css.map*/

@padmaia padmaia added the linear: turbopack Confirmed issue that is tracked by the Turbopack team. label Apr 10, 2024
@controversial
Copy link
Contributor

Turbopack uses Lightning CSS under the hood, and this is documented as one of Lightning CSS’s “unsupported features”:

Non-function syntax for the :local and :global pseudo classes.

However, this is also blocking my team’s adoption of next dev --turbo on several of our apps.

@RihuaChen
Copy link

I'm encountering the same issue. I've tested all versions in the 14.2.x series without success. Is there a plan to implement the requested feature ?

@RihuaChen
Copy link

Now I need to keep 14.1.4 version for next dev --turbo, it's so sad can not upgrade to new version

@kdy1 kdy1 self-assigned this Jul 25, 2024
@kdy1 kdy1 closed this as completed in 44b85cb Aug 7, 2024
ForsakenHarmony pushed a commit that referenced this issue Aug 16, 2024
### What?

Update `lightningcss` crate of next.js


### Why?

To apply parcel-bundler/lightningcss#784 and parcel-bundler/lightningcss#783

### How?

- Closes PACK-2933
- Closes PACK-3100
- Closes #66191
- Closes #64299
@controversial
Copy link
Contributor

controversial commented Aug 16, 2024

Why was this closed @kdy1? As far as I can tell, the change in parcel-bundler/lightningcss#784 was to make this syntax produce an error in lightningcss, rather than adding support for it.

This is still a missing feature from next --turbo that prevents parity with the webpack implementation, and stops teams from upgrading.

@timneutkens
Copy link
Member

At this point we're not planning on supporting that syntax as it's non-trivial to make this work in the CSS parser that Lightning CSS uses. I know that is unfortunate and probably not what you want to hear. Happy to review a PR to Lightning CSS that implements it ofcourse.

Usage of this particular syntax is quite low from looking around btw:

  • Usage of :global across all public GitHub repos using SourceGraph: 870 results
  • Usage of :global() across all public GitHub repos using SourceGraph: 13100 results

It's documented here as not supported here: https://nextjs.org/docs/architecture/turbopack#unsupported-features

@controversial
Copy link
Contributor

@timneutkens The feature in question depends on nesting features from scss/less to be useful, which is why there aren’t many results in .css files.

Including .(css|scss|less)—instead of just .cssit seems like :global { is used “in the wild” at about 1/4 the rate of :global(, rather than the 1/15 rate you suggest:

I find this feature really useful for cases where a third-party library renders a component with a nested structure, which I nest inside my CSS module styles.

Here’s one abbreviated example from my codebase

This would be much more cumbersome to express by wrapping each individual class name in :global():

.base { // outer wrapper, scoped using CSS modules
  :global {
    .react-select__control { // third-party library renders its own classnames without hooking into my CSS module
      // styles here...
      .react-select__value-container { /* styles here... */ }
      .react-select__placeholder,
      &:not(.react-select__control--is-focused):not(:hover) > .react-select__value-container:not(.react-select__value-container--has-value) {
        // styles here...
      }
    }
    .react-select__indicators { /* styles here... */ }
    .react-select__menu { /* styles here... */ }
    .react-select__menu-list { /* styles here... */ }
    .react-select__control--is-focused + .react-select__menu { /* styles here... */ }
    .react-select__option { /* styles here... */ }
  }
}

Your point that it would be nontrivial to implement in LightningCSS still stands, of course!

@Rototu
Copy link

Rototu commented Sep 12, 2024

Can confirm that where I'm working we're using :global exactly as @controversial mentioned, as well as for other similar libraries, and official support would definitely be much appreciated

@morganwu277
Copy link

We have lots of projects using the way exactly as @controversial as well and recently after upgrade, all broken. Hope we could get it supported soon.

Copy link
Contributor

github-actions bot commented Oct 5, 2024

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot added the locked label Oct 5, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. linear: turbopack Confirmed issue that is tracked by the Turbopack team. locked Turbopack Related to Turbopack with Next.js.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants