You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since postcss 8.5.24 wp-scripts build can produce a UTF-8 BOM (EF BB BF) in the middle of the extracted CSS.
In our case the BOM was inserted immediately before :root { --color-palette-primary: …; } so all CSS custom properties in the theme defined in :root were dropped.
There is no warning or build error.
Cause
The issue appears to be the interaction between sass-loader, Dart Sass, PostCSS 8.5.24, and mini-css-extract-plugin:
sass-loader sets style: 'compressed' for production builds (src/utils.js#L287). @wordpress/scripts passes no sassOptions, so Sass keeps its default charset: true.
With charset: true + style: 'compressed', Dart Sass prepends U+FEFF to the output of each compiled module whose CSS contains non-ASCII characters (a curly quote in content, an arrow, an emoj, etc).
Before postcss 8.5.23, postcss-loader stripped that BOM: Input recorded hasBOM but the stringifier never wrote it back. postcss 8.5.24 Preserve the BOM when stringifying postcss/postcss#2119 now re-emits it in Stringifier#root.
mini-css-extract-plugin then concatenates the chunk's CSS modules, so a BOM of module n ends up mid-file.
Proposed fix
Sass documents charset: false for this use case. In the Sass loader configuration webpack.config.js#L198-L208 :
Description
Since
postcss8.5.24wp-scripts buildcan produce a UTF-8 BOM (EF BB BF) in the middle of the extracted CSS.In our case the BOM was inserted immediately before
:root { --color-palette-primary: …; }so all CSS custom properties in the theme defined in:rootwere dropped.There is no warning or build error.
Cause
The issue appears to be the interaction between
sass-loader, Dart Sass, PostCSS 8.5.24, andmini-css-extract-plugin:sass-loadersetsstyle: 'compressed'for production builds (src/utils.js#L287).@wordpress/scriptspasses nosassOptions, so Sass keeps its defaultcharset: true.charset: true+style: 'compressed', Dart Sass prepends U+FEFF to the output of each compiled module whose CSS contains non-ASCII characters (a curly quote incontent, an arrow, an emoj, etc).postcss-loaderstripped that BOM:InputrecordedhasBOMbut the stringifier never wrote it back. postcss 8.5.24 Preserve the BOM when stringifying postcss/postcss#2119 now re-emits it inStringifier#root.mini-css-extract-pluginthen concatenates the chunk's CSS modules, so a BOM of module n ends up mid-file.Proposed fix
Sass documents
charset: falsefor this use case. In the Sass loader configuration webpack.config.js#L198-L208 :{ test: /\.(sc|sa)ss$/, use: [ ...cssLoaders, { loader: require.resolve( 'sass-loader' ), options: { sourceMap: ! isProduction, + sassOptions: { + charset: false, + }, }, }, ], },This prevents Sass from adding a BOM to individual CSS modules, so there is nothing for PostCSS to re-emit when the modules are concatenated.
Workarounds
Patch the sass rule in a project's own webpack config:
Or pin postcss:
"overrides": { "postcss": "8.5.23" }.Related
outputStyleoption, so production Sass is compiledcompressed(and BOM-prefixed) symfony/webpack-encore#1527 - same fallout in another build tool, fixed on their side.@layerat rule postcss/postcss#2122 - other 8.5.24 fallout (@layer).charsetoptionStep-by-step reproduction instructions
Expected: no output.
Actual: the BOM sits between the two concatenated modules, directly before
:root, making--brandunreachable in the browser.Confirming the trigger - pin postcss below 8.5.24 and rebuild:
Screenshots, screen recording, code snippet
No response
Environment info
No response
Please confirm that you have searched existing issues in the repo.
Please confirm that you have tested with all plugins deactivated except Gutenberg.
Please confirm which theme type you used for testing.