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

fix(build): fix css modules out of order issue from libraries #70087

Open
wants to merge 11 commits into
base: canary
Choose a base branch
from
26 changes: 12 additions & 14 deletions packages/next/src/build/webpack/config/blocks/css/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,18 +254,21 @@ export const css = curry(async function css(
const shouldIncludeExternalCSSImports =
!!ctx.experimental.craCompat || !!ctx.transpilePackages

// CSS modules & SASS modules support. They are allowed to be imported in anywhere.
/**
* CSS modules & SASS modules support.
* They are allowed to be imported in anywhere.
* CSS Modules must NOT be restricted by package.json `sideEffects`.
* Allows for unused stylesheets to be excluded from production builds.
*/
fns.push(
// CSS Modules should never have side effects. This setting will
// allow unused CSS to be removed from the production build.
// We ensure this by disallowing `:global()` CSS at the top-level
// via the `pure` mode in `css-loader`.
/**
* CSS Modules
*/
loader({
oneOf: [
// For app dir, we need to match the specific app layer.
ctx.hasAppDir
? markRemovable({
sideEffects: true,
test: regexCssModules,
issuerLayer: APP_LAYER_RULE,
use: [
Expand All @@ -285,7 +288,6 @@ export const css = curry(async function css(
})
: null,
markRemovable({
sideEffects: true,
test: regexCssModules,
issuerLayer: PAGES_LAYER_RULE,
use: getCssModuleLoader(
Expand All @@ -295,17 +297,14 @@ export const css = curry(async function css(
}),
].filter(nonNullable),
}),
// Opt-in support for Sass (using .scss or .sass extensions).
// Sass Modules should never have side effects. This setting will
// allow unused Sass to be removed from the production build.
// We ensure this by disallowing `:global()` Sass at the top-level
// via the `pure` mode in `css-loader`.
/**
* Sass Modules (.scss or .sass)
*/
loader({
oneOf: [
// For app dir, we need to match the specific app layer.
ctx.hasAppDir
? markRemovable({
sideEffects: true,
test: regexSassModules,
issuerLayer: APP_LAYER_RULE,
use: [
Expand All @@ -326,7 +325,6 @@ export const css = curry(async function css(
})
: null,
markRemovable({
sideEffects: true,
test: regexSassModules,
issuerLayer: PAGES_LAYER_RULE,
use: getCssModuleLoader(
Expand Down
15 changes: 15 additions & 0 deletions test/e2e/app-dir/css-order/app/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,21 @@ export default function Nav() {
Vendor
</Link>
</li>
<li>
<Link href={'/vendor/a'} id="vendor-a">
Vendor A
</Link>
</li>
<li>
<Link href={'/vendor/b'} id="vendor-b">
Vendor B
</Link>
</li>
<li>
<Link href={'/vendor/c'} id="vendor-c">
Vendor C
</Link>
</li>
</ul>
<h3>Pages</h3>
<ul>
Expand Down
13 changes: 13 additions & 0 deletions test/e2e/app-dir/css-order/app/vendor/a/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { SideEffectsArrayComponent } from 'side-effects-array-dep'
import Nav from '../../nav'

export default function Page() {
return (
<div>
<SideEffectsArrayComponent id="vendor-side-effects-array">
side effects: array
</SideEffectsArrayComponent>
<Nav />
</div>
)
}
13 changes: 13 additions & 0 deletions test/e2e/app-dir/css-order/app/vendor/b/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { SideEffectsComponent } from 'side-effects-dep'
import Nav from '../../nav'

export default function Page() {
return (
<div>
<SideEffectsComponent id="vendor-side-effects-true">
side effects: array
</SideEffectsComponent>
<Nav />
</div>
)
}
13 changes: 13 additions & 0 deletions test/e2e/app-dir/css-order/app/vendor/c/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { SideEffectsFalseComponent } from 'side-effects-false-dep'
import Nav from '../../nav'

export default function Page() {
return (
<div>
<SideEffectsFalseComponent id="vendor-side-effects-false">
side effects: array
</SideEffectsFalseComponent>
<Nav />
</div>
)
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions test/e2e/app-dir/css-order/css-order.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,27 @@ const PAGES: Record<
selector: '#vendor1',
color: 'rgb(0, 255, 0)',
},
'vendor-side-effects-array': {
group: 'side-effects-array',
url: '/vendor/a',
selector: '#vendor-side-effects-array',
background: 'rgb(0, 254, 0)',
color: 'rgb(254, 0, 0)',
},
'vendor-side-effects-true': {
group: 'side-effects-true',
url: '/vendor/b',
selector: '#vendor-side-effects-true',
background: 'rgb(0, 253, 0)',
color: 'rgb(253, 0, 0)',
},
'vendor-side-effects-false': {
group: 'side-effects-false',
url: '/vendor/c',
selector: '#vendor-side-effects-false',
background: 'rgb(0, 252, 0)',
color: 'rgb(252, 0, 0)',
},
}

const allPairs = getPairs(Object.keys(PAGES))
Expand Down
Loading