diff --git a/packages/next/src/build/webpack/config/blocks/css/loaders/client.ts b/packages/next/src/build/webpack/config/blocks/css/loaders/client.ts index c668f28aff5675..7802725d383c95 100644 --- a/packages/next/src/build/webpack/config/blocks/css/loaders/client.ts +++ b/packages/next/src/build/webpack/config/blocks/css/loaders/client.ts @@ -1,11 +1,13 @@ import type { webpack } from 'next/dist/compiled/webpack/webpack' export function getClientStyleLoader({ + optimizeCssModuleMappings, hasAppDir, isAppDir, isDevelopment, assetPrefix, }: { + optimizeCssModuleMappings?: boolean hasAppDir: boolean isAppDir?: boolean isDevelopment: boolean @@ -47,7 +49,15 @@ export function getClientStyleLoader({ loader: MiniCssExtractPlugin.loader, options: { publicPath: `${assetPrefix}/_next/`, - esModule: false, + // Activating the mini-css-extract-plugin esmodules export + // allows webpack to optimize the module tree and to inline + // the css module class names directly into react components + // + // Activating this option will break one edge case: + // import { default } from './file.module.css' + // Therefore it is behind the experimental flag + // `optimizeCssModuleMappings` + esModule: optimizeCssModuleMappings ? true : false, }, } } diff --git a/packages/next/src/build/webpack/config/blocks/css/loaders/global.ts b/packages/next/src/build/webpack/config/blocks/css/loaders/global.ts index bb43722bf535e0..50bb9d6059e935 100644 --- a/packages/next/src/build/webpack/config/blocks/css/loaders/global.ts +++ b/packages/next/src/build/webpack/config/blocks/css/loaders/global.ts @@ -16,6 +16,7 @@ export function getGlobalCssLoader( // loader loaders.push( getClientStyleLoader({ + optimizeCssModuleMappings: ctx.experimental.optimizeCssModuleMappings, hasAppDir: ctx.hasAppDir, isAppDir: ctx.isAppDir, isDevelopment: ctx.isDevelopment, diff --git a/packages/next/src/build/webpack/config/blocks/css/loaders/modules.ts b/packages/next/src/build/webpack/config/blocks/css/loaders/modules.ts index 1479c5d17c9d3b..6bec032ccbafe5 100644 --- a/packages/next/src/build/webpack/config/blocks/css/loaders/modules.ts +++ b/packages/next/src/build/webpack/config/blocks/css/loaders/modules.ts @@ -16,6 +16,7 @@ export function getCssModuleLoader( // loader loaders.push( getClientStyleLoader({ + optimizeCssModuleMappings: ctx.experimental.optimizeCssModuleMappings, hasAppDir: ctx.hasAppDir, isAppDir: ctx.isAppDir, isDevelopment: ctx.isDevelopment, diff --git a/packages/next/src/build/webpack/config/blocks/css/loaders/next-font.ts b/packages/next/src/build/webpack/config/blocks/css/loaders/next-font.ts index 10ec131f9e0afb..dd99700fd3a1a7 100644 --- a/packages/next/src/build/webpack/config/blocks/css/loaders/next-font.ts +++ b/packages/next/src/build/webpack/config/blocks/css/loaders/next-font.ts @@ -15,6 +15,7 @@ export function getNextFontLoader( // loader loaders.push( getClientStyleLoader({ + optimizeCssModuleMappings: ctx.experimental.optimizeCssModuleMappings, hasAppDir: ctx.hasAppDir, isDevelopment: ctx.isDevelopment, assetPrefix: ctx.assetPrefix, diff --git a/packages/next/src/server/config-schema.ts b/packages/next/src/server/config-schema.ts index 8d0978edb0f4fc..9d1f6265a11daa 100644 --- a/packages/next/src/server/config-schema.ts +++ b/packages/next/src/server/config-schema.ts @@ -275,6 +275,7 @@ export const configSchema: zod.ZodType = z.lazy(() => caseSensitiveRoutes: z.boolean().optional(), disableOptimizedLoading: z.boolean().optional(), disablePostcssPresetEnv: z.boolean().optional(), + optimizeCssModuleMappings: z.boolean().optional(), esmExternals: z.union([z.boolean(), z.literal('loose')]).optional(), serverActions: z .object({ diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index a10f1748a137a1..a7a84ca1e33720 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -241,6 +241,11 @@ export interface ExperimentalConfig { // Use Record as critters doesn't export its Option type // https://github.com/GoogleChromeLabs/critters/blob/a590c05f9197b656d2aeaae9369df2483c26b072/packages/critters/src/index.d.ts optimizeCss?: boolean | Record + /** + * `optimizeCssModuleMappings` enables a compiler optimization that reduces the size of js code for css modules. + * However it will break `import { default } from './example.module.css'` in .js files. + */ + optimizeCssModuleMappings?: boolean nextScriptWorkers?: boolean scrollRestoration?: boolean externalDir?: boolean