Skip to content

Commit

Permalink
New CSS chunking algorithm (#63157)
Browse files Browse the repository at this point in the history
### What?

This fixes more CSS ordering issues with production and webpack dev.

* CSS Modules must not be side effect free as side effect free modules
are per definition order independent which is not true for CSS
* fix order of iterating module references
* disable splitChunks for CSS
* special chunking for CSS with loose and strict mode
* more test cases

Closes PACK-2709
  • Loading branch information
sokra authored Mar 18, 2024
1 parent af5b31c commit 46a5882
Show file tree
Hide file tree
Showing 56 changed files with 3,348 additions and 528 deletions.
32 changes: 9 additions & 23 deletions packages/next/src/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ import {
createAppRouterApiAliases,
} from './create-compiler-aliases'
import { hasCustomExportOutput } from '../export/utils'
import { MergeCssChunksPlugin } from './webpack/plugins/merge-css-chunks-plugin'
import { CssChunkingPlugin } from './webpack/plugins/css-chunking-plugin'

type ExcludesFalse = <T>(x: T | false) => x is T
type ClientEntries = {
Expand Down Expand Up @@ -1005,10 +1005,12 @@ export default async function getBaseWebpackConfig(

const libCacheGroup = {
test(module: {
type: string
size: Function
nameForCondition: Function
}): boolean {
return (
!module.type?.startsWith('css') &&
module.size() > 160000 &&
/node_modules[/\\]/.test(module.nameForCondition() || '')
)
Expand Down Expand Up @@ -1046,31 +1048,17 @@ export default async function getBaseWebpackConfig(
}

// client chunking
const cssCacheGroup = {
test: /\.(css|sass|scss)$/i,
chunks: 'all' as const,
enforce: true,
type: /css/,
minChunks: 2,
priority: 100,
}
return {
// Keep main and _app chunks unsplitted in webpack 5
// as we don't need a separate vendor chunk from that
// and all other chunk depend on them so there is no
// duplication that need to be pulled out.
chunks: (chunk: any) =>
!/^(polyfills|main|pages\/_app)$/.test(chunk.name),
cacheGroups: appDir
? {
css: cssCacheGroup,
framework: frameworkCacheGroup,
lib: libCacheGroup,
}
: {
framework: frameworkCacheGroup,
lib: libCacheGroup,
},
cacheGroups: {
framework: frameworkCacheGroup,
lib: libCacheGroup,
},
maxInitialRequests: 25,
minSize: 20000,
}
Expand Down Expand Up @@ -1891,10 +1879,8 @@ export default async function getBaseWebpackConfig(
new NextFontManifestPlugin({
appDir,
}),
!dev &&
isClient &&
config.experimental.mergeCssChunks &&
new MergeCssChunksPlugin(),
isClient &&
new CssChunkingPlugin(config.experimental.cssChunking === 'strict'),
!dev &&
isClient &&
new (require('./webpack/plugins/telemetry-plugin').TelemetryPlugin)(
Expand Down
8 changes: 4 additions & 4 deletions packages/next/src/build/webpack/config/blocks/css/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ export const css = curry(async function css(
// For app dir, we need to match the specific app layer.
ctx.hasAppDir
? markRemovable({
sideEffects: false,
sideEffects: true,
test: regexCssModules,
issuerLayer: APP_LAYER_RULE,
use: [
Expand All @@ -283,7 +283,7 @@ export const css = curry(async function css(
})
: null,
markRemovable({
sideEffects: false,
sideEffects: true,
test: regexCssModules,
issuerLayer: PAGES_LAYER_RULE,
use: getCssModuleLoader(
Expand All @@ -303,7 +303,7 @@ export const css = curry(async function css(
// For app dir, we need to match the specific app layer.
ctx.hasAppDir
? markRemovable({
sideEffects: false,
sideEffects: true,
test: regexSassModules,
issuerLayer: APP_LAYER_RULE,
use: [
Expand All @@ -324,7 +324,7 @@ export const css = curry(async function css(
})
: null,
markRemovable({
sideEffects: false,
sideEffects: true,
test: regexSassModules,
issuerLayer: PAGES_LAYER_RULE,
use: getCssModuleLoader(
Expand Down
Loading

0 comments on commit 46a5882

Please sign in to comment.