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

PostCSS not applied to imports via composes #10079

Open
7 tasks done
elisehein opened this issue Sep 12, 2022 · 8 comments · May be fixed by #16018
Open
7 tasks done

PostCSS not applied to imports via composes #10079

elisehein opened this issue Sep 12, 2022 · 8 comments · May be fixed by #16018
Labels
feat: css p2-nice-to-have Not breaking anything but nice to have (priority)

Comments

@elisehein
Copy link

Describe the bug

I'm trying to have styles included in a CSS module via composes processed by PostCSS, but it's not happening. All other styles are processed by PostCSS correctly.

Take the following CSS modules and PostCSS config:

{
  "plugins": {
    "postcss-preset-env": {
      "browsers": "defaults, ie >= 11",
      "importFrom": [
        "./src/variables.css"
      ]
    },
    "postcss-nested": { }
  }
}
/* variables.css */
:root {
  --color-red: red;
  --color-blue: blue;
}

/* component.module.css */
.component {
  color: var(--color-red);

  .nested {
    width: 100%;
  }
}

/* main.module.css */
.main {
  composes: component from "./component.module.css";
  color: var(--color-blue);

  .nested {
    display: block;
  }
}

Expected result

I exect to see the styles I include with .main via `composes: component from "./component.module.css" to be valid (with PostCSS plugins applied). Expected result:

 ._component_xs2hm_5 {
  color: red;
  color: var(--color-red);
 }

 ._component_xs2hm_5 ._nested_xs2hm_13 {
  width: 100%;
}

._foo_1mrk0_1 {
  color: blue;
  color: var(--color-blue);
}

._foo_1mrk0_1 ._nested_1mrk0_7 {
  width: 100%;
}

Actual result

The styles included via composes are not processed by PostCSS. They are included in the <style> tag as-is, resulting in invalid CSS.

 ._component_xs2hm_5 {
  color: var(--color-red);

  ._nested_xs2hm_13 {
    width: 100%;
  }
}

._foo_1mrk0_1 {
  color: blue;
  color: var(--color-blue);
}

._foo_1mrk0_1 ._nested-bar_1mrk0_7 {
  width: 100%;
}

The same bug can be observed in the production build.

There was a similar issue logged and fixed in vue-loader: vuejs/vue-loader#959

Reproduction

https://github.com/elisehein/vite-postcss-compose-repro

System Info

System:
    OS: macOS 12.4
    CPU: (10) arm64 Apple M1 Pro
    Memory: 721.78 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.16.0 - ~/.asdf/installs/nodejs/16.16.0/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 8.15.0 - ~/.asdf/plugins/nodejs/shims/npm
    Watchman: 2022.05.16.00 - /usr/local/bin/watchman
  Browsers:
    Firefox: 103.0.2
    Safari: 15.5
    Safari Technology Preview: 15.4
  npmPackages:
    @vitejs/plugin-legacy: ^1.8.2 => 1.8.2 
    @vitejs/plugin-react: ^1.0.0 => 1.3.2 
    vite: ^3.0.2 => 3.1.0

Used Package Manager

npm

Logs

No response

Validations

@sapphi-red
Copy link
Member

Vite puts postcss plugins in the following order.

[postcssImport, postcssModules, ...userPlugins, postcssViteRewriteUrl]

In this order ([postcssModules, postcssNested]), the output is:

._component_8abi2_1 {
  color: var(--color-red);

  ._nested_8abi2_7 {
    width: 100%;
  }
}

._foo_15itx_1 {
  color: red;
}

But when the order is [postcssNested, postcssModules], the output is:

._component_8abi2_1 {
  color: var(--color-red);
}._component_8abi2_1 ._nested_8abi2_7 {
    width: 100%;
  }._foo_15itx_1 {
  color: red;
}

stackblitz

So I think we need an option to apply a plugin before default ones, or reorders the plugins.

@sapphi-red sapphi-red added feat: css p2-nice-to-have Not breaking anything but nice to have (priority) and removed pending triage labels Sep 12, 2022
@patak-dev
Copy link
Member

We had a related PR to change the order of PostCSS plugins, and have the user ones before the internal ones:

In that case, it was closed because the issue should have been fixed upstream. But it could count as another case where having the chance to inject plugins before Vite plugins could have been useful. Maybe we could have a { order: 'pre', ...plugin } for PostCSS plugins too?

@sapphi-red
Copy link
Member

I took a look around postcss plugin specs. Maybe it's possible to solve on plugins' side?

https://github.com/postcss/postcss/releases/tag/8.0.0#:~:text=Plugins%20will%20re%2Dvisit%20changed%20nodes%20to%20reduce%20compatibility%20issues%20between%20plugins.%20Now%20the%20order%20of%20plugins%20in%20your%20PostCSS%20config%20will%20be%20less%20important.
#764 #296

I feel it's better to avoid extending the plugin interface of PostCSS.

@patak-dev
Copy link
Member

Another point in favor of waiting here is that there is a chance we end up replacing PostCSS with LigthingCSS in the future

@basmilius
Copy link

Another point in favor of waiting here is that there is a chance we end up replacing PostCSS with LigthingCSS in the future

Any news on when this will happen? I'm deciding if it's worth waithing for a fix to this issue or just go with plain old css :)

@Inok
Copy link

Inok commented Feb 8, 2023

The current approach with postcss-modules running as the first plugin seems wrong because postcss doesn't apply user plugins in that case.
Now it's either composes X from '...' or other plugins, but not both. Or at least composed file must be a native CSS file because it won't be processed anyway.

Precisely, now I can't compose a rule from another module and customize that rule with a custom media query at the same time.

Is there any chance that the issue will be fixed somehow?

@alkorlos
Copy link

alkorlos commented Aug 9, 2023

@patak-dev LigthingCSS faster then PostCSS and probably LigthingCSS or CSSTree better for minifying and other tasks.
But not LigthingCSS or CSSTree have not so many plugins as PostCSS. And LigthingCSS written in rust, plugins for it can be written on JS, but it's harder than PostCSS.

It is unlikely that in the near future it will be possible to completely abandon PostCSS, while there is no support injecting plugins before except this

[postcssImport, postcssModules, ...userPlugins, postcssViteRewriteUrl]

This isuue and #12336 will be relevant.

@privatenumber
Copy link
Sponsor Contributor

I've implemented a fix via https://github.com/privatenumber/vite-css-modules (which is getting integrated into Vite core via #16018).

Testing and feedback will be appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat: css p2-nice-to-have Not breaking anything but nice to have (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants