Skip to content

Commit

Permalink
avoid merging global css in a way that leaks into other chunk groups
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Jul 2, 2024
1 parent 6795597 commit 71bd613
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 0 deletions.
34 changes: 34 additions & 0 deletions packages/next/src/build/webpack/plugins/css-chunking-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ const MIN_CSS_CHUNK_SIZE = 30 * 1024
*/
const MAX_CSS_CHUNK_SIZE = 100 * 1024

function isGlobalCss(module: Module) {
return !/\.module\.(css|scss|sass)$/.test(module.nameForCondition() || '')
}

type ChunkState = {
chunk: Chunk
modules: Module[]
Expand Down Expand Up @@ -125,6 +129,8 @@ export class CssChunkingPlugin {

// Process through all modules
for (const startModule of remainingModules) {
let globalCssMode = isGlobalCss(startModule)

// The current position of processing in all selected chunks
let allChunkStates = new Map(chunkStatesByModule.get(startModule)!)

Expand Down Expand Up @@ -225,8 +231,36 @@ export class CssChunkingPlugin {
}
}
}

// Global CSS must not leak into unrelated chunks
const nextIsGlobalCss = isGlobalCss(nextModule)
if (nextIsGlobalCss && globalCssMode) {
if (allChunkStates.size !== nextChunkStates.size) {
// Fast check
continue
}
}
if (globalCssMode) {
for (const chunkState of nextChunkStates.keys()) {
if (!allChunkStates.has(chunkState)) {
// Global CSS would leak into chunkState
continue loop
}
}
}
if (nextIsGlobalCss) {
for (const chunkState of allChunkStates.keys()) {
if (!nextChunkStates.has(chunkState)) {
// Global CSS would leak into chunkState
continue loop
}
}
}
potentialNextModules.delete(nextModule)
currentSize += size
if (nextIsGlobalCss) {
globalCssMode = true
}
for (const [chunkState, i] of nextChunkStates) {
if (allChunkStates.has(chunkState)) {
// This reduces the request count of the chunk group
Expand Down
3 changes: 3 additions & 0 deletions test/e2e/app-dir/css-order/app/base.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#hello {
color: rgb(255, 0, 0);
}
12 changes: 12 additions & 0 deletions test/e2e/app-dir/css-order/app/global-first/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import '../base.css'
import './style.css'
import Nav from '../nav'

export default function Page() {
return (
<div>
<p id="hello">hello world</p>
<Nav />
</div>
)
}
3 changes: 3 additions & 0 deletions test/e2e/app-dir/css-order/app/global-first/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#hello {
color: rgb(0, 255, 0);
}
12 changes: 12 additions & 0 deletions test/e2e/app-dir/css-order/app/global-second/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import '../base.css'
import './style.css'
import Nav from '../nav'

export default function Page() {
return (
<div>
<p id="hello">hello world</p>
<Nav />
</div>
)
}
3 changes: 3 additions & 0 deletions test/e2e/app-dir/css-order/app/global-second/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#hello {
color: rgb(0, 0, 255);
}
10 changes: 10 additions & 0 deletions test/e2e/app-dir/css-order/app/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ export default function Nav() {
Partial Reversed B
</Link>
</li>
<li>
<Link href={'/global-first'} id="global-first">
Global First
</Link>
</li>
<li>
<Link href={'/global-second'} id="global-second">
Global Second
</Link>
</li>
</ul>
<h3>Pages</h3>
<ul>
Expand Down
14 changes: 14 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 @@ -183,6 +183,20 @@ const PAGES: Record<
color: 'rgb(255, 55, 255)',
background: 'rgba(0, 0, 0, 0)',
},
'global-first': {
group: 'global',
conflict: true,
url: '/global-first',
selector: '#hello',
color: 'rgb(0, 255, 0)',
},
'global-second': {
group: 'global',
conflict: true,
url: '/global-second',
selector: '#hello',
color: 'rgb(0, 0, 255)',
},
}

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

0 comments on commit 71bd613

Please sign in to comment.