Skip to content

Optimize css module mappings inside the javascript code #62637

@jantimon

Description

@jantimon

Link to the code that reproduces this issue

https://github.com/jantimon/reproduction-nextjs-module-css-optimization

To Reproduce

npm i 
npm run build
Route (pages)                             Size     First Load JS
┌ ○ /                                     780 B          78.9 kB
├   └ css/6ab5fea530a348de.css            367 B
└ ○ /404                                  182 B          78.3 kB
+ First Load JS shared by all             78.1 kB
  ├ chunks/framework-2c16ac744b6cdea6.js  45.2 kB
  ├ chunks/main-d7239acbfe0deb02.js       31.9 kB
  └ other shared chunks (total)           945 B

○  (Static)  prerendered as static content

now apply the patch and build again

npm run patch
rm -rf .next
npm run build
Route (pages)                             Size     First Load JS
┌ ○ /                                     682 B          78.7 kB
├   └ css/6ab5fea530a348de.css            367 B
└ ○ /404                                  182 B          78.2 kB
+ First Load JS shared by all             78 kB
  ├ chunks/framework-2c16ac744b6cdea6.js  45.2 kB
  ├ chunks/main-d7239acbfe0deb02.js       31.9 kB
  └ other shared chunks (total)           907 B

○  (Static)  prerendered as static content

Current vs. Expected behavior

the current behavior is not broken but with the proposed patch we could save ~100bytes in this tiny example

100b is not much but for larger projects this would be more significant

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.1.0: Mon Oct  9 21:27:24 PDT 2023; root:xnu-10002.41.9~6/RELEASE_ARM64_T6000
  Available memory (MB): 65536
  Available CPU cores: 10
Binaries:
  Node: 20.9.0
  npm: 10.1.0
  Yarn: 1.22.19
  pnpm: 8.15.1
Relevant Packages:
  next: 14.1.1-canary.77 // Latest available version is detected (14.1.1-canary.77).
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.1.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Not sure

Which stage(s) are affected? (Select all that apply)

next build (local), Vercel (Deployed), Other (Deployed)

Additional context

Why is it smaller?

It uses webpacks esmodule optimzations to get rid of the module which maps the class names:

 (self.webpackChunk_N_E = self.webpackChunk_N_E || []).push([
     [405], {
-        8312: function(n, e, i) {
+        8312: function(n, i, e) {
             (window.__NEXT_P = window.__NEXT_P || []).push(["/", function() {
-                return i(6209)
+                return e(2061)
             }])
         },
-        6209: function(n, e, i) {
+        2061: function(n, i, e) {
             "use strict";
-            i.r(e), i.d(e, {
+            e.r(i), e.d(i, {
                 default: function() {
                     return s
                 }
             });
-            var a = i(5893),
-                c = i(9672),
-                t = i.n(c);
+            var c = e(5893),
+                a = "home_navigationItem__YfA2i";
 
             function s() {
-                return (0, a.jsxs)("div", {
-                    className: t().container,
-                    children: [(0, a.jsx)("header", {
-                        className: t().header,
-                        children: (0, a.jsx)("h1", {
-                            className: t().title,
+                return (0, c.jsxs)("div", {
+                    className: "home_container__8Eizc",
+                    children: [(0, c.jsx)("header", {
+                        className: "home_header__1mjVn",
+                        children: (0, c.jsx)("h1", {
+                            className: "home_title__AmF9d",
                             children: "Hello, World!"
                         })
-                    }), (0, a.jsxs)("div", {
-                        className: t().content,
-                        children: [(0, a.jsx)("nav", {
-                            className: t().sidebar,
-                            children: (0, a.jsxs)("ul", {
-                                className: t().navigation,
-                                children: [(0, a.jsx)("li", {
-                                    className: t().navigationItem,
+                    }), (0, c.jsxs)("div", {
+                        className: "home_content__WS_Hd",
+                        children: [(0, c.jsx)("nav", {
+                            className: "home_sidebar__znTuH",
+                            children: (0, c.jsxs)("ul", {
+                                className: "home_navigation__fEwRH",
+                                children: [(0, c.jsx)("li", {
+                                    className: a,
                                     children: "Home"
-                                }), (0, a.jsx)("li", {
-                                    className: t().navigationItem,
+                                }), (0, c.jsx)("li", {
+                                    className: a,
                                     children: "About"
-                                }), (0, a.jsx)("li", {
-                                    className: t().navigationItem,
+                                }), (0, c.jsx)("li", {
+                                    className: a,
                                     children: "Services"
-                                }), (0, a.jsx)("li", {
-                                    className: t().navigationItem,
+                                }), (0, c.jsx)("li", {
+                                    className: a,
                                     children: "Contact"
                                 })]
                             })
-                        }), (0, a.jsx)("main", {
-                            className: t().main,
-                            children: (0, a.jsx)("p", {
-                                className: t().loremIpsum,
+                        }), (0, c.jsx)("main", {
+                            className: "home_main__Q1Z7j",
+                            children: (0, c.jsx)("p", {
+                                className: "home_loremIpsum__W_bYN",
                                 children: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt, nunc id aliquam tincidunt, nisl mauris fringilla magna, ac aliquet nunc mauris nec nunc. Nulla facilisi. Sed euismod, nisl ut lacinia tincidunt, nunc nunc ultrices nunc, vitae aliquet nunc nunc eget nunc. Sed id nunc nec nunc tincidunt lacinia. Nulla facilisi. Sed euismod, nisl ut lacinia tincidunt, nunc nunc ultrices nunc, vitae aliquet nunc nunc eget nunc. Sed id nunc nec nunc tincidunt lacinia."
                             })
                         })]
-                    }), (0, a.jsx)("footer", {
-                        className: t().footer,
-                        children: (0, a.jsx)("p", {
-                            className: t().footerText,
+                    }), (0, c.jsx)("footer", {
+                        className: "home_footer__0MnFT",
+                        children: (0, c.jsx)("p", {
+                            className: "home_footerText__hY6yc",
                             children: "\xa9 2022 Your Company"
                         })
                     })]
                 })
             }
-        },
-        9672: function(n) {
-            n.exports = {
-                container: "home_container__8Eizc",
-                header: "home_header__1mjVn",
-                title: "home_title__AmF9d",
-                content: "home_content__WS_Hd",
-                sidebar: "home_sidebar__znTuH",
-                navigation: "home_navigation__fEwRH",
-                navigationItem: "home_navigationItem__YfA2i",
-                main: "home_main__Q1Z7j",
-                loremIpsum: "home_loremIpsum__W_bYN",
-                footer: "home_footer__0MnFT",
-                footerText: "home_footerText__hY6yc"
-            }
         }
     },
     function(n) {

Possible patch

diff --git a/node_modules/next/dist/build/webpack/config/blocks/css/loaders/client.js b/node_modules/next/dist/build/webpack/config/blocks/css/loaders/client.js
index e482b46..1b35d91 100644
--- a/node_modules/next/dist/build/webpack/config/blocks/css/loaders/client.js
+++ b/node_modules/next/dist/build/webpack/config/blocks/css/loaders/client.js
@@ -39,7 +39,7 @@ function getClientStyleLoader({ hasAppDir, isAppDir, isDevelopment, assetPrefix
         loader: MiniCssExtractPlugin.loader,
         options: {
             publicPath: `${assetPrefix}/_next/`,
-            esModule: false
+            esModule: true
         }
     };
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssue was opened via the bug report template.lockedstaleThe issue has not seen recent activity.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions