What problem does this address?
@wordpress/wp-build inlines all imported stylesheets into the JS bundle as runtime-injected <style> elements (with data-wp-hash deduplication). This means that if someone adds import './style.scss' in a JS file, it silently "works" at runtime, making it easy to miss that this is the wrong pattern.
In most packages, stylesheets should be imported through the package's root-level style.scss, not directly in JS. Importing in JS bypasses the standard stylesheet pipeline and causes the styles to be injected at runtime via document.head.appendChild. This has several problems:
- Redundancy. If the stylesheet is already in the root
style.scss chain, it gets loaded twice.
- No RTL processing. Most packages rely on the build-time RTL transformation to generate
-rtl.css stylesheets. Runtime-injected styles bypass this entirely, so any directional styles (margins, paddings, borders, etc.) will be broken in RTL locales.
I found three existing cases of this:
packages/block-editor/src/components/block-visibility/modal.js imports ./style.scss. This is redundant because the same file is already in the root packages/block-editor/src/style.scss.
packages/editor/src/components/collaborators-presence/index.tsx imports ./styles/collaborators-presence.scss, and list.tsx imports ./styles/collaborators-list.scss. These are not in the root stylesheet at all, so they're only loaded through the runtime injection.
What is your proposed solution?
What problem does this address?
@wordpress/wp-buildinlines all imported stylesheets into the JS bundle as runtime-injected<style>elements (withdata-wp-hashdeduplication). This means that if someone addsimport './style.scss'in a JS file, it silently "works" at runtime, making it easy to miss that this is the wrong pattern.In most packages, stylesheets should be imported through the package's root-level
style.scss, not directly in JS. Importing in JS bypasses the standard stylesheet pipeline and causes the styles to be injected at runtime viadocument.head.appendChild. This has several problems:style.scsschain, it gets loaded twice.-rtl.cssstylesheets. Runtime-injected styles bypass this entirely, so any directional styles (margins, paddings, borders, etc.) will be broken in RTL locales.I found three existing cases of this:
packages/block-editor/src/components/block-visibility/modal.jsimports./style.scss. This is redundant because the same file is already in the rootpackages/block-editor/src/style.scss.packages/editor/src/components/collaborators-presence/index.tsximports./styles/collaborators-presence.scss, andlist.tsximports./styles/collaborators-list.scss. These are not in the root stylesheet at all, so they're only loaded through the runtime injection.What is your proposed solution?
collaborators-presencestylesheets, also add them topackages/editor/src/style.scss..scss/.cssfiles in JS/TS files. This should flag side-effect-only imports likeimport './style.scss'while allowing CSS module imports that have a binding (e.g.,import styles from './style.module.scss').wp-buildinline injection to CSS modules only. Currently thecompileInlineStyletransform inwp-buildprocesses all.css/.scssimports the same way. If it only applied the runtime injection to.module.css/.module.scssfiles, developers would notice that the styles are missing.