Skip to content

Commit 333489d

Browse files
authored
Turbopack: fix postcss in RSC CSS (#82554)
### What? make sure to apply PostCSS on .module.css that is requested from RSC. Fixes a regression from #82448 Closes #82545
1 parent b850812 commit 333489d

File tree

8 files changed

+70
-27
lines changed

8 files changed

+70
-27
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { ReactNode } from 'react'
2+
export default function Root({ children }: { children: ReactNode }) {
3+
return (
4+
<html>
5+
<body>{children}</body>
6+
</html>
7+
)
8+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
:not(html) {
2+
.main {
3+
color: red;
4+
}
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import styles from './page.module.css'
2+
3+
export default function Page() {
4+
return <p className={styles.main}>hello world</p>
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { nextTestSetup } from 'e2e-utils'
2+
3+
describe('css-modules-rsc-postcss', () => {
4+
const { next } = nextTestSetup({
5+
files: __dirname,
6+
dependencies: {
7+
'postcss-nested': '4.2.1',
8+
},
9+
})
10+
11+
it('should compile successfully and apply the correct styles', async () => {
12+
const browser = await next.browser('/')
13+
expect(await browser.elementByCss('p').getComputedCss('color')).toBe(
14+
'rgb(0, 128, 0)'
15+
)
16+
})
17+
})
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* @type {import('next').NextConfig}
3+
*/
4+
const nextConfig = {}
5+
6+
module.exports = nextConfig
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const plugin = () => {
2+
return {
3+
postcssPlugin: 'color-change',
4+
Declaration: {
5+
color(prop) {
6+
prop.value = 'green'
7+
},
8+
},
9+
}
10+
}
11+
plugin.postcss = true
12+
module.exports = plugin
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
plugins: ['postcss-nested', require.resolve('./plugin')],
3+
}

turbopack/crates/turbopack/src/module_options/mod.rs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,17 @@ impl ModuleOptions {
162162
// only then be processed with Webpack/PostCSS).
163163
//
164164
// Note that this is not an exhaustive condition for PostCSS/Webpack, but excludes certain
165-
// cases, so it should be added conjunctively together with the `module_css_condition` rule.
165+
// cases, so it should be added conjunctively together with CSS Module rule.
166166
//
167167
// If module css, then only when (Inner or Analyze or Compose)
168168
// <=> (not (module css)) or (Inner or Analyzer or Compose)
169-
let module_css_external_transform_conditions = vec![
169+
//
170+
// So only if this is not a CSS module, or one of the special reference type constraints.
171+
let module_css_external_transform_conditions = RuleCondition::Any(vec![
172+
RuleCondition::not(module_css_condition.clone()),
170173
RuleCondition::ReferenceType(ReferenceType::Css(CssReferenceSubType::Inner)),
171174
RuleCondition::ReferenceType(ReferenceType::Css(CssReferenceSubType::Analyze)),
172-
RuleCondition::ReferenceType(ReferenceType::Css(CssReferenceSubType::Compose)),
173-
];
175+
]);
174176

175177
let mut ts_preprocess = vec![];
176178
let mut ecma_preprocess = vec![];
@@ -505,22 +507,14 @@ impl ModuleOptions {
505507
};
506508

507509
rules.push(ModuleRule::new(
508-
RuleCondition::Any(vec![
509-
RuleCondition::All(vec![
510-
RuleCondition::Any(vec![
511-
RuleCondition::ResourcePathEndsWith(".css".to_string()),
512-
RuleCondition::ContentTypeStartsWith("text/css".to_string()),
513-
]),
514-
RuleCondition::not(module_css_condition.clone()),
510+
RuleCondition::All(vec![
511+
RuleCondition::Any(vec![
512+
// Both CSS and CSS Modules
513+
RuleCondition::ResourcePathEndsWith(".css".to_string()),
514+
RuleCondition::ContentTypeStartsWith("text/css".to_string()),
515+
module_css_condition.clone(),
515516
]),
516-
RuleCondition::All(
517-
[
518-
vec![module_css_condition.clone()],
519-
// see comment on module_css_external_transform_conditions
520-
module_css_external_transform_conditions.clone(),
521-
]
522-
.concat(),
523-
),
517+
module_css_external_transform_conditions.clone(),
524518
]),
525519
vec![ModuleRuleEffect::SourceTransforms(ResolvedVc::cell(vec![
526520
ResolvedVc::upcast(
@@ -703,14 +697,7 @@ impl ModuleOptions {
703697
RuleCondition::ResourceBasePathGlob(Glob::new(key.clone()).await?)
704698
},
705699
RuleCondition::not(RuleCondition::ResourceIsVirtualSource),
706-
// see comment on module_css_external_transform_conditions
707-
RuleCondition::Any(
708-
[
709-
vec![RuleCondition::not(module_css_condition.clone())],
710-
module_css_external_transform_conditions.clone(),
711-
]
712-
.concat(),
713-
),
700+
module_css_external_transform_conditions.clone(),
714701
]),
715702
vec![ModuleRuleEffect::SourceTransforms(ResolvedVc::cell(vec![
716703
ResolvedVc::upcast(

0 commit comments

Comments
 (0)