Skip to content

Conversation

@aduth
Copy link
Member

@aduth aduth commented Oct 24, 2025

What?

Updates build script to inline contents of CSS modules into built JavaScript rather than emitting separate stylesheets.

Follow-up to #72305

Why?

It may end up simplifying dependency tracking and developer experience for consuming from packages which provide styles through CSS modules. For example, #72305 mentions "Probably move the styles in the stylesheet to an inline style attribute" as a follow-up action item because the inclusion of a separate stylesheet adds additional developer friction.

On the other hand, it may be worth keeping an eye on this and revisiting down the line, since there may be some ramifications:

  • If the package is loaded multiple times, the current experience is that a unique style tag is added each time it's loaded
    • This might be possible to mitigate if we override default behavior of how esbuild-sass-plugin generates code for adding the style tag (i.e. make it idempotent)
  • Injecting stylesheets may create challenges for sites employing a Content Security Policy
  • There may be performance ramifications of inlining styles through JavaScript compared to more traditional stylesheets

Testing Instructions

  1. Run npm run build
  2. Verify that the outputs of the bundled theme package include inlined styles: grep -C 5 _root_ build/scripts/theme/index.js
      themeProviderStyles
    };
  }

  // packages/theme/build-module/style.module.css
  var css = `._root_th78q_1 {
	display: contents;
}
`;
  document.head.appendChild(document.createElement("style")).appendChild(document.createTextNode(css));
  var style_default = {
    "root": "_root_th78q_1"
  };

  // packages/theme/build-module/theme-provider.js
  function cssObjectToText(values) {
    return Object.entries(values).map(([key, value]) => `${key}: ${value};`).join("");

@github-actions
Copy link

Warning: Type of PR label mismatch

To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.

  • Type-related labels to choose from: [Type] Automated Testing, [Type] Breaking Change, [Type] Bug, [Type] Build Tooling, [Type] Code Quality, [Type] Copy, [Type] Developer Documentation, [Type] Enhancement, [Type] Experimental, [Type] Feature, [Type] New API, [Type] Task, [Type] Technical Prototype, [Type] Performance, [Type] Project Management, [Type] Regression, [Type] Security, [Type] WP Core Ticket, Backport from WordPress Core, Gutenberg Plugin, New Block, [Type] Iteration.
  • Labels found: .

Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task.

@github-actions
Copy link

github-actions bot commented Oct 24, 2025

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: aduth <[email protected]>
Co-authored-by: youknowriad <[email protected]>
Co-authored-by: tyxla <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Comment on lines -978 to +801
const jsonFiles = await glob(
normalizePath( path.join( packageDir, 'src/**/*.json' ) ),
const assetFiles = await glob(
normalizePath(
path.join( packageDir, `src/**/*.${ ASSET_EXTENSIONS }` )
),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build happens as separate passes:

  1. Transpile the original source into packages/theme/build-module
  2. Bundle the script into build/scripts/theme

Evaluating the CSS modules happens at the bundling step, so the module.css files have to be available in the build-module output, hence the changes here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evaluating the CSS modules happens at the bundling step, so the module.css files have to be available in the build-module output, hence the changes here.

This is something that I'm not sure about. I don't think we should force package users to have a build tool that understands CSS modules imports until this becomes a standard.

So for now, I believe inlining CSS within JS should ideally be done during the transpiling step.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll look at this. It's not straightforward since it appears that the Sass plugin only evaluates CSS modules when bundle: true is configured in the ESBuild build, and we don't want to bundle during the transpilation step.

A few initial ideas:

  • I recall seeing something about using a combination of bundle: true and defining dependencies as externals to let the transpilation step bundle the result but continue externalizing dependencies
  • Alternatively, we might need to do something more custom and tap into ESBuild plugin load hooks. This might be something we'd want to do anyways as a solution to (1) duplicate script tags and (2) moving away from PostCSS.

Copy link
Member Author

@aduth aduth Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we've kinda painted ourselves into a corner by wanting transpilation step to not bundle, but CSS modules be part of the transpilation step, and inlining the styles.

Styles are normally handled as part of the bundling step. Without bundling, ESBuild won't even evaluate the imports of a file, so we can't really alter how those styles are loaded. Similarly, ESBuild's built-in handling for CSS modules only happens when bundling is enabled, and the way they generate class names for CSS modules only protects against conflicts when bundling the entire application.

I tried enabling bundling while keeping "everything" external†, but ESBuild errors when trying to set relative paths as external, and without being able to do that, the bundling causes each transpiled file to include the contents of all its local package files. If we could bundle the package down to a single file, it'd probably work, but I'm guessing we don't want to do that if we need to support importing subpaths (ideally we wouldn't support this in a greenfield project, but we've got a lot of backwards-compatibility).

Another problem we'll have is that this sort of style inlining is inherently a side effect, which creates a lot of challenges around supporting tree-shaking without a lot of maintenance burden around how we maintain sideEffects. Maybe we can use some wildcard patterns to help here, though.

All this kinda had me leaning back toward a solution where we process the individual CSS modules, create a shim JavaScript file in place, and generate a CSS file... before realizing this is the exact solution we already have and are trying to replace 😅 We could probably use an optimized alternative to PostCSS (LightningCSS) to address that concern. I'm personally not as sold on trying to avoid CSS files altogether.

I'll continue to tinker with exploring a solution which essentially combines parts of what we already have (shimming JavaScript), but inlining a script to inject a style tag rather than emit a stylesheet.

† Externals plugin:

{
  name: "externals",
  setup(build) {
    build.onResolve({ filter: /^/ }, (args) => {
      return {
        path: args.path,
        external: !args.path.startsWith(packageDir),
      };
    });
  },
},

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On tree shaking: Would it be fair to say that yes, CSS modules are side effects but they are only needed if the file that imports it is used (the component). Is this kind of side effect something we can "codify" somehow?

On transpiling and bundling I'm not strongly against bundling the packages that have CSS directly into packages/build-* which means that the "bundling step" becomes just a "copying step" for these packages (in addition to adding a global variable if they are scripts). Now I don't really know if that helps or not here? and I don't really know whether this should be default for all packages or not (or if it should be limited to only some of them)

On eliminating CSS files from builds and inlining JS I'm also open to alternatives, that said I do feel like we don't have a good compelling alternative that addresses the need for both "tree shaking" and "lazy loading of modules".

  • If I import "Button" ideally I just get the button CSS in my bundle
  • If I import a "WP script module" dynamically, I would like for the CSS of the script module to be loaded as well automatically.

I think these are the two things we should aim to solve.

Copy link
Contributor

@sgomes sgomes Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sgomes Do you have a link to some canonical article (or maybe a P2 post you wrote in the past) that describes the CSS-in-JS issues in detail?

I don't have anything up-to-date, because I haven't looked at it in some time (since thankfully CSS-in-JS isn't quite as popular nowadays). The fundamental problem, as I recall, were CSS-in-JS approaches that did their work at runtime, rather than at build time, and the overhead in managing all that. The problem isn't injecting pre-computed style tags at runtime; every lazy CSS approach does that, since we don't have async CSS loading natively on the web platform. The problem is computing dynamic style tags (e.g. ones that depend on component props) at runtime, and managing all the plumbing for that.

This is an old (Dec. 2019) article I remember reading and thinking was very thorough, when I was looking closer at CSS-in-JS: https://calendar.perfplanet.com/2019/the-unseen-performance-costs-of-css-in-js-in-react-apps/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is computing dynamic style tags (e.g. ones that depend on component props) at runtime, and managing all the plumbing for that.

That's good news for us, because with our approach we're not doing this at all. All our styles are static CSS strings. We only use CSS-in-JS as a distribution method: instead of shipping the string in a .css file, we ship it as a JS string and insert it using DOM API.

Copy link
Contributor

@sgomes sgomes Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good news for us, because with our approach we're not doing this at all. All our styles are static CSS strings. We only use CSS-in-JS as a distribution method: instead of shipping the string in a .css file, we ship it as a JS string and insert it using DOM API.

Right, exactly. And I'd always assumed stuffing CSS in JS as a distribution method was a problem in and of itself, but it turns out that the impact of having large string literals inside a JS file is much smaller than I thought.

So while the approach isn't ideal (it's still more expensive than simply pointing the browser at a CSS file, and it's worse for debugging), it didn't seem to be a performance problem in practice, at least as far as I could measure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the useful feedback everyone!

@youknowriad, with all things said so far, I'm OK to move on like this for now, but I'd suggest keeping an eye on it and maybe considering introducing a mechanism for distributing CSS through dedicated asset files at some point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One place where this approach will fail completely is server-side rendering. On the server, styles are shipped differently. Our problem is that the document.head.appendChild calls are hardcoded. If they were abstracted into something like emotionCache.insert(), the build environment could provide the exact implementation.

Maybe we should adopt some tiny subset of Emotion or another CSS-in-JS library 🙂 Otherwise we're just implemeting a bad version of something that already exists.

@aduth aduth added the [Type] Build Tooling Issues or PRs related to build tooling label Oct 24, 2025
@github-actions
Copy link

github-actions bot commented Oct 24, 2025

Flaky tests detected in 8c62679.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/18909842186
📝 Reported issues:

@aduth aduth force-pushed the update/build-css-modules-inline branch from 0c7b6df to 7f351af Compare October 29, 2025 13:22
aduth added 2 commits October 29, 2025 09:33
These are now loaded dynamically through the bundled JavaScript code
These are no longer generated
Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's ship this and iterate on the transpilation of the css modules separately.

@github-actions
Copy link

Size Change: +17 B (0%)

Total Size: 2.37 MB

Filename Size Change
build/scripts/theme/index.min.js 28.4 kB +69 B (+0.24%)
build/styles/theme/style.css 0 B -52 B (removed) 🏆
ℹ️ View Unchanged
Filename Size
build/modules/a11y/index.min.js 355 B
build/modules/block-editor/utils/fit-text-frontend.min.js 550 B
build/modules/block-library/accordion/view.min.js 520 B
build/modules/block-library/file/view.min.js 346 B
build/modules/block-library/form/view.min.js 528 B
build/modules/block-library/image/view.min.js 1.66 kB
build/modules/block-library/navigation/view.min.js 1.03 kB
build/modules/block-library/query/view.min.js 518 B
build/modules/block-library/search/view.min.js 498 B
build/modules/interactivity-router/full-page.min.js 451 B
build/modules/interactivity-router/index.min.js 11.6 kB
build/modules/interactivity/index.min.js 14.9 kB
build/modules/latex-to-mathml/index.min.js 56.5 kB
build/modules/latex-to-mathml/loader.min.js 131 B
build/scripts/a11y/index.min.js 1.06 kB
build/scripts/annotations/index.min.js 2.38 kB
build/scripts/api-fetch/index.min.js 2.83 kB
build/scripts/autop/index.min.js 2.18 kB
build/scripts/blob/index.min.js 631 B
build/scripts/block-directory/index.min.js 8.04 kB
build/scripts/block-editor/index.min.js 295 kB
build/scripts/block-library/index.min.js 267 kB
build/scripts/block-serialization-default-parser/index.min.js 1.16 kB
build/scripts/block-serialization-spec-parser/index.min.js 3.08 kB
build/scripts/blocks/index.min.js 56.2 kB
build/scripts/commands/index.min.js 17.4 kB
build/scripts/components/index.min.js 271 kB
build/scripts/compose/index.min.js 13.8 kB
build/scripts/core-commands/index.min.js 4.13 kB
build/scripts/core-data/index.min.js 85.7 kB
build/scripts/customize-widgets/index.min.js 12.3 kB
build/scripts/data-controls/index.min.js 793 B
build/scripts/data/index.min.js 9.61 kB
build/scripts/date/index.min.js 23.6 kB
build/scripts/deprecated/index.min.js 755 B
build/scripts/dom-ready/index.min.js 476 B
build/scripts/dom/index.min.js 4.91 kB
build/scripts/edit-post/index.min.js 16.8 kB
build/scripts/edit-site/index.min.js 228 kB
build/scripts/edit-widgets/index.min.js 20 kB
build/scripts/editor/index.min.js 282 kB
build/scripts/element/index.min.js 5.19 kB
build/scripts/escape-html/index.min.js 586 B
build/scripts/format-library/index.min.js 10.6 kB
build/scripts/hooks/index.min.js 1.83 kB
build/scripts/html-entities/index.min.js 494 B
build/scripts/i18n/index.min.js 2.46 kB
build/scripts/is-shallow-equal/index.min.js 568 B
build/scripts/keyboard-shortcuts/index.min.js 1.57 kB
build/scripts/keycodes/index.min.js 1.53 kB
build/scripts/latex-to-mathml/index.min.js 56.7 kB
build/scripts/list-reusable-blocks/index.min.js 2.44 kB
build/scripts/media-utils/index.min.js 64.5 kB
build/scripts/notices/index.min.js 1.11 kB
build/scripts/nux/index.min.js 1.88 kB
build/scripts/patterns/index.min.js 8.62 kB
build/scripts/plugins/index.min.js 2.14 kB
build/scripts/preferences-persistence/index.min.js 2.15 kB
build/scripts/preferences/index.min.js 3.31 kB
build/scripts/primitives/index.min.js 1.01 kB
build/scripts/priority-queue/index.min.js 1.61 kB
build/scripts/private-apis/index.min.js 1.05 kB
build/scripts/react-i18n/index.min.js 832 B
build/scripts/react-refresh-entry/index.min.js 9.44 kB
build/scripts/react-refresh-runtime/index.min.js 3.59 kB
build/scripts/redux-routine/index.min.js 3.36 kB
build/scripts/reusable-blocks/index.min.js 2.92 kB
build/scripts/rich-text/index.min.js 12.9 kB
build/scripts/router/index.min.js 5.96 kB
build/scripts/server-side-render/index.min.js 1.9 kB
build/scripts/shortcode/index.min.js 1.58 kB
build/scripts/style-engine/index.min.js 2.31 kB
build/scripts/token-list/index.min.js 740 B
build/scripts/undo-manager/index.min.js 915 B
build/scripts/url/index.min.js 3.98 kB
build/scripts/vendors/react-dom.min.js 43 kB
build/scripts/vendors/react-jsx-runtime.min.js 691 B
build/scripts/vendors/react.min.js 4.27 kB
build/scripts/viewport/index.min.js 1.22 kB
build/scripts/warning/index.min.js 454 B
build/scripts/widgets/index.min.js 7.83 kB
build/scripts/wordcount/index.min.js 1.04 kB
build/styles/block-directory/style-rtl.css 1.05 kB
build/styles/block-directory/style.css 1.05 kB
build/styles/block-editor/content-rtl.css 4.81 kB
build/styles/block-editor/content.css 4.8 kB
build/styles/block-editor/default-editor-styles-rtl.css 224 B
build/styles/block-editor/default-editor-styles.css 224 B
build/styles/block-editor/style-rtl.css 16.2 kB
build/styles/block-editor/style.css 16.2 kB
build/styles/block-library/accordion-heading/style-rtl.css 340 B
build/styles/block-library/accordion-heading/style.css 340 B
build/styles/block-library/accordion-item/style-rtl.css 213 B
build/styles/block-library/accordion-item/style.css 213 B
build/styles/block-library/accordion-panel/style-rtl.css 99 B
build/styles/block-library/accordion-panel/style.css 99 B
build/styles/block-library/archives/editor-rtl.css 61 B
build/styles/block-library/archives/editor.css 61 B
build/styles/block-library/archives/style-rtl.css 90 B
build/styles/block-library/archives/style.css 90 B
build/styles/block-library/audio/editor-rtl.css 149 B
build/styles/block-library/audio/editor.css 151 B
build/styles/block-library/audio/style-rtl.css 132 B
build/styles/block-library/audio/style.css 132 B
build/styles/block-library/audio/theme-rtl.css 134 B
build/styles/block-library/audio/theme.css 134 B
build/styles/block-library/avatar/editor-rtl.css 115 B
build/styles/block-library/avatar/editor.css 115 B
build/styles/block-library/avatar/style-rtl.css 104 B
build/styles/block-library/avatar/style.css 104 B
build/styles/block-library/breadcrumbs/style-rtl.css 203 B
build/styles/block-library/breadcrumbs/style.css 203 B
build/styles/block-library/button/editor-rtl.css 265 B
build/styles/block-library/button/editor.css 265 B
build/styles/block-library/button/style-rtl.css 554 B
build/styles/block-library/button/style.css 554 B
build/styles/block-library/buttons/editor-rtl.css 291 B
build/styles/block-library/buttons/editor.css 291 B
build/styles/block-library/buttons/style-rtl.css 349 B
build/styles/block-library/buttons/style.css 349 B
build/styles/block-library/calendar/style-rtl.css 239 B
build/styles/block-library/calendar/style.css 239 B
build/styles/block-library/categories/editor-rtl.css 132 B
build/styles/block-library/categories/editor.css 131 B
build/styles/block-library/categories/style-rtl.css 152 B
build/styles/block-library/categories/style.css 152 B
build/styles/block-library/classic-rtl.css 179 B
build/styles/block-library/classic.css 179 B
build/styles/block-library/code/editor-rtl.css 53 B
build/styles/block-library/code/editor.css 53 B
build/styles/block-library/code/style-rtl.css 139 B
build/styles/block-library/code/style.css 139 B
build/styles/block-library/code/theme-rtl.css 122 B
build/styles/block-library/code/theme.css 122 B
build/styles/block-library/columns/editor-rtl.css 108 B
build/styles/block-library/columns/editor.css 108 B
build/styles/block-library/columns/style-rtl.css 421 B
build/styles/block-library/columns/style.css 421 B
build/styles/block-library/comment-author-avatar/editor-rtl.css 124 B
build/styles/block-library/comment-author-avatar/editor.css 124 B
build/styles/block-library/comment-author-name/style-rtl.css 72 B
build/styles/block-library/comment-author-name/style.css 72 B
build/styles/block-library/comment-content/style-rtl.css 120 B
build/styles/block-library/comment-content/style.css 120 B
build/styles/block-library/comment-date/style-rtl.css 65 B
build/styles/block-library/comment-date/style.css 65 B
build/styles/block-library/comment-edit-link/style-rtl.css 70 B
build/styles/block-library/comment-edit-link/style.css 70 B
build/styles/block-library/comment-reply-link/style-rtl.css 71 B
build/styles/block-library/comment-reply-link/style.css 71 B
build/styles/block-library/comment-template/style-rtl.css 191 B
build/styles/block-library/comment-template/style.css 191 B
build/styles/block-library/comments-pagination-numbers/editor-rtl.css 122 B
build/styles/block-library/comments-pagination-numbers/editor.css 121 B
build/styles/block-library/comments-pagination/editor-rtl.css 168 B
build/styles/block-library/comments-pagination/editor.css 168 B
build/styles/block-library/comments-pagination/style-rtl.css 201 B
build/styles/block-library/comments-pagination/style.css 201 B
build/styles/block-library/comments-title/editor-rtl.css 75 B
build/styles/block-library/comments-title/editor.css 75 B
build/styles/block-library/comments/editor-rtl.css 842 B
build/styles/block-library/comments/editor.css 842 B
build/styles/block-library/comments/style-rtl.css 637 B
build/styles/block-library/comments/style.css 637 B
build/styles/block-library/common-rtl.css 1.11 kB
build/styles/block-library/common.css 1.11 kB
build/styles/block-library/cover/editor-rtl.css 631 B
build/styles/block-library/cover/editor.css 631 B
build/styles/block-library/cover/style-rtl.css 1.7 kB
build/styles/block-library/cover/style.css 1.69 kB
build/styles/block-library/details/editor-rtl.css 65 B
build/styles/block-library/details/editor.css 65 B
build/styles/block-library/details/style-rtl.css 86 B
build/styles/block-library/details/style.css 86 B
build/styles/block-library/editor-elements-rtl.css 75 B
build/styles/block-library/editor-elements.css 75 B
build/styles/block-library/editor-rtl.css 11.6 kB
build/styles/block-library/editor.css 11.6 kB
build/styles/block-library/elements-rtl.css 54 B
build/styles/block-library/elements.css 54 B
build/styles/block-library/embed/editor-rtl.css 331 B
build/styles/block-library/embed/editor.css 331 B
build/styles/block-library/embed/style-rtl.css 419 B
build/styles/block-library/embed/style.css 419 B
build/styles/block-library/embed/theme-rtl.css 133 B
build/styles/block-library/embed/theme.css 133 B
build/styles/block-library/file/editor-rtl.css 324 B
build/styles/block-library/file/editor.css 324 B
build/styles/block-library/file/style-rtl.css 278 B
build/styles/block-library/file/style.css 278 B
build/styles/block-library/footnotes/style-rtl.css 198 B
build/styles/block-library/footnotes/style.css 197 B
build/styles/block-library/form-input/editor-rtl.css 229 B
build/styles/block-library/form-input/editor.css 229 B
build/styles/block-library/form-input/style-rtl.css 366 B
build/styles/block-library/form-input/style.css 366 B
build/styles/block-library/form-submission-notification/editor-rtl.css 344 B
build/styles/block-library/form-submission-notification/editor.css 341 B
build/styles/block-library/form-submit-button/style-rtl.css 69 B
build/styles/block-library/form-submit-button/style.css 69 B
build/styles/block-library/freeform/editor-rtl.css 2.59 kB
build/styles/block-library/freeform/editor.css 2.59 kB
build/styles/block-library/gallery/editor-rtl.css 615 B
build/styles/block-library/gallery/editor.css 616 B
build/styles/block-library/gallery/style-rtl.css 1.84 kB
build/styles/block-library/gallery/style.css 1.84 kB
build/styles/block-library/gallery/theme-rtl.css 108 B
build/styles/block-library/gallery/theme.css 108 B
build/styles/block-library/group/editor-rtl.css 335 B
build/styles/block-library/group/editor.css 335 B
build/styles/block-library/group/style-rtl.css 103 B
build/styles/block-library/group/style.css 103 B
build/styles/block-library/group/theme-rtl.css 79 B
build/styles/block-library/group/theme.css 79 B
build/styles/block-library/heading/style-rtl.css 188 B
build/styles/block-library/heading/style.css 188 B
build/styles/block-library/html/editor-rtl.css 357 B
build/styles/block-library/html/editor.css 358 B
build/styles/block-library/image/editor-rtl.css 763 B
build/styles/block-library/image/editor.css 763 B
build/styles/block-library/image/style-rtl.css 1.6 kB
build/styles/block-library/image/style.css 1.59 kB
build/styles/block-library/image/theme-rtl.css 137 B
build/styles/block-library/image/theme.css 137 B
build/styles/block-library/latest-comments/style-rtl.css 355 B
build/styles/block-library/latest-comments/style.css 354 B
build/styles/block-library/latest-posts/editor-rtl.css 139 B
build/styles/block-library/latest-posts/editor.css 138 B
build/styles/block-library/latest-posts/style-rtl.css 520 B
build/styles/block-library/latest-posts/style.css 520 B
build/styles/block-library/list/style-rtl.css 107 B
build/styles/block-library/list/style.css 107 B
build/styles/block-library/loginout/style-rtl.css 61 B
build/styles/block-library/loginout/style.css 61 B
build/styles/block-library/math/editor-rtl.css 105 B
build/styles/block-library/math/editor.css 105 B
build/styles/block-library/math/style-rtl.css 61 B
build/styles/block-library/math/style.css 61 B
build/styles/block-library/media-text/editor-rtl.css 321 B
build/styles/block-library/media-text/editor.css 320 B
build/styles/block-library/media-text/style-rtl.css 543 B
build/styles/block-library/media-text/style.css 542 B
build/styles/block-library/more/editor-rtl.css 393 B
build/styles/block-library/more/editor.css 393 B
build/styles/block-library/navigation-link/editor-rtl.css 626 B
build/styles/block-library/navigation-link/editor.css 628 B
build/styles/block-library/navigation-link/style-rtl.css 190 B
build/styles/block-library/navigation-link/style.css 188 B
build/styles/block-library/navigation-submenu/editor-rtl.css 295 B
build/styles/block-library/navigation-submenu/editor.css 294 B
build/styles/block-library/navigation/editor-rtl.css 2.24 kB
build/styles/block-library/navigation/editor.css 2.24 kB
build/styles/block-library/navigation/style-rtl.css 2.27 kB
build/styles/block-library/navigation/style.css 2.25 kB
build/styles/block-library/nextpage/editor-rtl.css 392 B
build/styles/block-library/nextpage/editor.css 392 B
build/styles/block-library/page-list/editor-rtl.css 356 B
build/styles/block-library/page-list/editor.css 356 B
build/styles/block-library/page-list/style-rtl.css 192 B
build/styles/block-library/page-list/style.css 192 B
build/styles/block-library/paragraph/editor-rtl.css 251 B
build/styles/block-library/paragraph/editor.css 251 B
build/styles/block-library/paragraph/style-rtl.css 341 B
build/styles/block-library/paragraph/style.css 340 B
build/styles/block-library/post-author-biography/style-rtl.css 74 B
build/styles/block-library/post-author-biography/style.css 74 B
build/styles/block-library/post-author-name/style-rtl.css 69 B
build/styles/block-library/post-author-name/style.css 69 B
build/styles/block-library/post-author/style-rtl.css 188 B
build/styles/block-library/post-author/style.css 189 B
build/styles/block-library/post-comments-count/style-rtl.css 72 B
build/styles/block-library/post-comments-count/style.css 72 B
build/styles/block-library/post-comments-form/editor-rtl.css 96 B
build/styles/block-library/post-comments-form/editor.css 96 B
build/styles/block-library/post-comments-form/style-rtl.css 525 B
build/styles/block-library/post-comments-form/style.css 525 B
build/styles/block-library/post-comments-link/style-rtl.css 71 B
build/styles/block-library/post-comments-link/style.css 71 B
build/styles/block-library/post-content/style-rtl.css 61 B
build/styles/block-library/post-content/style.css 61 B
build/styles/block-library/post-date/style-rtl.css 62 B
build/styles/block-library/post-date/style.css 62 B
build/styles/block-library/post-excerpt/editor-rtl.css 71 B
build/styles/block-library/post-excerpt/editor.css 71 B
build/styles/block-library/post-excerpt/style-rtl.css 155 B
build/styles/block-library/post-excerpt/style.css 155 B
build/styles/block-library/post-featured-image/editor-rtl.css 719 B
build/styles/block-library/post-featured-image/editor.css 717 B
build/styles/block-library/post-featured-image/style-rtl.css 347 B
build/styles/block-library/post-featured-image/style.css 347 B
build/styles/block-library/post-navigation-link/style-rtl.css 215 B
build/styles/block-library/post-navigation-link/style.css 214 B
build/styles/block-library/post-template/style-rtl.css 414 B
build/styles/block-library/post-template/style.css 414 B
build/styles/block-library/post-terms/style-rtl.css 96 B
build/styles/block-library/post-terms/style.css 96 B
build/styles/block-library/post-time-to-read/style-rtl.css 70 B
build/styles/block-library/post-time-to-read/style.css 70 B
build/styles/block-library/post-title/style-rtl.css 162 B
build/styles/block-library/post-title/style.css 162 B
build/styles/block-library/preformatted/style-rtl.css 125 B
build/styles/block-library/preformatted/style.css 125 B
build/styles/block-library/pullquote/editor-rtl.css 133 B
build/styles/block-library/pullquote/editor.css 133 B
build/styles/block-library/pullquote/style-rtl.css 365 B
build/styles/block-library/pullquote/style.css 365 B
build/styles/block-library/pullquote/theme-rtl.css 176 B
build/styles/block-library/pullquote/theme.css 176 B
build/styles/block-library/query-pagination-numbers/editor-rtl.css 121 B
build/styles/block-library/query-pagination-numbers/editor.css 118 B
build/styles/block-library/query-pagination/editor-rtl.css 154 B
build/styles/block-library/query-pagination/editor.css 154 B
build/styles/block-library/query-pagination/style-rtl.css 237 B
build/styles/block-library/query-pagination/style.css 237 B
build/styles/block-library/query-title/style-rtl.css 64 B
build/styles/block-library/query-title/style.css 64 B
build/styles/block-library/query-total/style-rtl.css 64 B
build/styles/block-library/query-total/style.css 64 B
build/styles/block-library/query/editor-rtl.css 438 B
build/styles/block-library/query/editor.css 438 B
build/styles/block-library/quote/style-rtl.css 238 B
build/styles/block-library/quote/style.css 238 B
build/styles/block-library/quote/theme-rtl.css 233 B
build/styles/block-library/quote/theme.css 236 B
build/styles/block-library/read-more/style-rtl.css 131 B
build/styles/block-library/read-more/style.css 131 B
build/styles/block-library/reset-rtl.css 472 B
build/styles/block-library/reset.css 472 B
build/styles/block-library/rss/editor-rtl.css 126 B
build/styles/block-library/rss/editor.css 126 B
build/styles/block-library/rss/style-rtl.css 284 B
build/styles/block-library/rss/style.css 283 B
build/styles/block-library/search/editor-rtl.css 199 B
build/styles/block-library/search/editor.css 199 B
build/styles/block-library/search/style-rtl.css 665 B
build/styles/block-library/search/style.css 666 B
build/styles/block-library/search/theme-rtl.css 113 B
build/styles/block-library/search/theme.css 113 B
build/styles/block-library/separator/editor-rtl.css 100 B
build/styles/block-library/separator/editor.css 100 B
build/styles/block-library/separator/style-rtl.css 248 B
build/styles/block-library/separator/style.css 248 B
build/styles/block-library/separator/theme-rtl.css 195 B
build/styles/block-library/separator/theme.css 195 B
build/styles/block-library/shortcode/editor-rtl.css 286 B
build/styles/block-library/shortcode/editor.css 286 B
build/styles/block-library/site-logo/editor-rtl.css 773 B
build/styles/block-library/site-logo/editor.css 770 B
build/styles/block-library/site-logo/style-rtl.css 218 B
build/styles/block-library/site-logo/style.css 218 B
build/styles/block-library/site-tagline/editor-rtl.css 87 B
build/styles/block-library/site-tagline/editor.css 87 B
build/styles/block-library/site-tagline/style-rtl.css 65 B
build/styles/block-library/site-tagline/style.css 65 B
build/styles/block-library/site-title/editor-rtl.css 85 B
build/styles/block-library/site-title/editor.css 85 B
build/styles/block-library/site-title/style-rtl.css 143 B
build/styles/block-library/site-title/style.css 143 B
build/styles/block-library/social-link/editor-rtl.css 314 B
build/styles/block-library/social-link/editor.css 314 B
build/styles/block-library/social-links/editor-rtl.css 339 B
build/styles/block-library/social-links/editor.css 338 B
build/styles/block-library/social-links/style-rtl.css 1.51 kB
build/styles/block-library/social-links/style.css 1.51 kB
build/styles/block-library/spacer/editor-rtl.css 346 B
build/styles/block-library/spacer/editor.css 346 B
build/styles/block-library/spacer/style-rtl.css 48 B
build/styles/block-library/spacer/style.css 48 B
build/styles/block-library/style-rtl.css 15.6 kB
build/styles/block-library/style.css 15.6 kB
build/styles/block-library/table-of-contents/style-rtl.css 83 B
build/styles/block-library/table-of-contents/style.css 83 B
build/styles/block-library/table/editor-rtl.css 394 B
build/styles/block-library/table/editor.css 394 B
build/styles/block-library/table/style-rtl.css 641 B
build/styles/block-library/table/style.css 640 B
build/styles/block-library/table/theme-rtl.css 152 B
build/styles/block-library/table/theme.css 152 B
build/styles/block-library/tag-cloud/editor-rtl.css 92 B
build/styles/block-library/tag-cloud/editor.css 92 B
build/styles/block-library/tag-cloud/style-rtl.css 248 B
build/styles/block-library/tag-cloud/style.css 248 B
build/styles/block-library/template-part/editor-rtl.css 368 B
build/styles/block-library/template-part/editor.css 368 B
build/styles/block-library/template-part/theme-rtl.css 113 B
build/styles/block-library/template-part/theme.css 113 B
build/styles/block-library/term-count/style-rtl.css 63 B
build/styles/block-library/term-count/style.css 63 B
build/styles/block-library/term-description/style-rtl.css 126 B
build/styles/block-library/term-description/style.css 126 B
build/styles/block-library/term-name/style-rtl.css 62 B
build/styles/block-library/term-name/style.css 62 B
build/styles/block-library/term-template/editor-rtl.css 225 B
build/styles/block-library/term-template/editor.css 225 B
build/styles/block-library/term-template/style-rtl.css 114 B
build/styles/block-library/term-template/style.css 114 B
build/styles/block-library/text-columns/editor-rtl.css 95 B
build/styles/block-library/text-columns/editor.css 95 B
build/styles/block-library/text-columns/style-rtl.css 165 B
build/styles/block-library/text-columns/style.css 165 B
build/styles/block-library/theme-rtl.css 715 B
build/styles/block-library/theme.css 719 B
build/styles/block-library/verse/style-rtl.css 98 B
build/styles/block-library/verse/style.css 98 B
build/styles/block-library/video/editor-rtl.css 415 B
build/styles/block-library/video/editor.css 416 B
build/styles/block-library/video/style-rtl.css 202 B
build/styles/block-library/video/style.css 202 B
build/styles/block-library/video/theme-rtl.css 134 B
build/styles/block-library/video/theme.css 134 B
build/styles/commands/style-rtl.css 999 B
build/styles/commands/style.css 1 kB
build/styles/components/style-rtl.css 14 kB
build/styles/components/style.css 14 kB
build/styles/customize-widgets/style-rtl.css 1.44 kB
build/styles/customize-widgets/style.css 1.44 kB
build/styles/edit-post/classic-rtl.css 426 B
build/styles/edit-post/classic.css 427 B
build/styles/edit-post/style-rtl.css 3.33 kB
build/styles/edit-post/style.css 3.33 kB
build/styles/edit-site/posts-rtl.css 9.85 kB
build/styles/edit-site/posts.css 9.84 kB
build/styles/edit-site/style-rtl.css 15.4 kB
build/styles/edit-site/style.css 15.4 kB
build/styles/edit-widgets/style-rtl.css 4.59 kB
build/styles/edit-widgets/style.css 4.59 kB
build/styles/editor/style-rtl.css 18.1 kB
build/styles/editor/style.css 18.1 kB
build/styles/format-library/style-rtl.css 308 B
build/styles/format-library/style.css 308 B
build/styles/list-reusable-blocks/style-rtl.css 1.02 kB
build/styles/list-reusable-blocks/style.css 1.02 kB
build/styles/nux/style-rtl.css 622 B
build/styles/nux/style.css 618 B
build/styles/patterns/style-rtl.css 703 B
build/styles/patterns/style.css 703 B
build/styles/preferences/style-rtl.css 415 B
build/styles/preferences/style.css 415 B
build/styles/reusable-blocks/style-rtl.css 275 B
build/styles/reusable-blocks/style.css 275 B
build/styles/widgets/style-rtl.css 1.17 kB
build/styles/widgets/style.css 1.18 kB

compressed-size-action

@aduth aduth changed the title Update build to inline CSS modules stylesheet content Build: Inline CSS modules stylesheet content Oct 29, 2025
@aduth aduth merged commit 9c5138f into trunk Oct 29, 2025
39 checks passed
@aduth aduth deleted the update/build-css-modules-inline branch October 29, 2025 15:10
@github-actions github-actions bot added this to the Gutenberg 22.1 milestone Oct 29, 2025
@aduth
Copy link
Member Author

aduth commented Oct 29, 2025

With incorporating styles in transpiled output, maybe we can look at a way that avoids it being a side-effect in the way that the styles are appended automatically when the component is imported, and instead make it a side-effect of the actual component rendering.

One idea I had here is that because CSS modules are imported as an object, we could (ab)use object getters to append the styles. This would be in conflict with React render functions not having side-effects, but ... maybe it's not practically a problem as long as we ensure the behavior is idempotent?

The "correct" way of handling this would be using useInsertionEffect (h/t @jsnajdr for the pointer), which might either require some code helpers to incorporate, or some more extensive transformation as part of the transpilation step.

@youknowriad
Copy link
Contributor

So we don't really support SASS for these inline css imports? Should we?

@aduth
Copy link
Member Author

aduth commented Oct 29, 2025

So we don't really support SASS for these inline css imports? Should we?

Not at the moment. I haven't personally seen a demonstrated need, and at least with the theming work being built out leaning heavily on CSS properties, that's going to be the primary way for accessing "variables". Are there other features we're missing that aren't available in native CSS these days?

@aduth
Copy link
Member Author

aduth commented Oct 29, 2025

One idea I had here is that because CSS modules are imported as an object, we could (ab)use object getters to append the styles. This would be in conflict with React render functions not having side-effects, but ... maybe it's not practically a problem as long as we ensure the behavior is idempotent?

I put together a proof-of-concept branch for this at https://github.com/WordPress/gutenberg/compare/try/bundled-css-modules :

It ends up producing something like this in the build:

// packages/theme/build-module/style.module.css.js

export default {
	get [ "root" ]() {
		const style = document.createElement( 'style' );
		style.styleSheet.cssText = "._root_th78q_1 {\n\tdisplay: contents;\n}\n";
		document.body.appendChild( style );
		delete this[ "root" ];
		return ( this[ "root" ] = "_root_th78q_1" );
	}
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Type] Build Tooling Issues or PRs related to build tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants