Skip to content

Commit 4508a5e

Browse files
authored
fix: handle css with BOM (#9467)
1 parent ac56c26 commit 4508a5e

File tree

7 files changed

+46
-14
lines changed

7 files changed

+46
-14
lines changed

crates/rspack_core/src/utils/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ mod module_rules;
2424
mod property_access;
2525
mod property_name;
2626
mod queue;
27+
mod remove_bom;
2728
mod runtime;
2829
mod source;
2930
pub mod task_loop;
@@ -45,6 +46,7 @@ pub use self::module_rules::*;
4546
pub use self::property_access::*;
4647
pub use self::property_name::*;
4748
pub use self::queue::*;
49+
pub use self::remove_bom::*;
4850
pub use self::runtime::*;
4951
pub use self::source::*;
5052
pub use self::template::*;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use std::sync::Arc;
2+
3+
use rspack_sources::{ReplaceSource, Source, SourceExt};
4+
5+
pub fn remove_bom(s: Arc<dyn Source>) -> Arc<dyn Source> {
6+
if s.source().starts_with('\u{feff}') {
7+
let mut s = ReplaceSource::new(s);
8+
s.replace(0, 3, "", None);
9+
s.boxed()
10+
} else {
11+
s
12+
}
13+
}

crates/rspack_plugin_css/src/parser_and_generator/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rspack_cacheable::{
1212
};
1313
use rspack_core::{
1414
diagnostics::map_box_diagnostics_to_module_parse_diagnostics,
15+
remove_bom,
1516
rspack_sources::{BoxSource, ConcatSource, RawStringSource, ReplaceSource, Source, SourceExt},
1617
BuildMetaDefaultObject, BuildMetaExportsType, ChunkGraph, Compilation, ConstDependency,
1718
CssExportsConvention, Dependency, DependencyId, DependencyRange, DependencyTemplate,
@@ -133,6 +134,7 @@ impl ParserAndGenerator for CssParserAndGenerator {
133134
BuildMetaDefaultObject::Redirect
134135
};
135136

137+
let source = remove_bom(source);
136138
let source_code = source.source();
137139
let resource_path = &resource_data.resource_path;
138140
let cached_source_code = OnceCell::new();

crates/rspack_plugin_javascript/src/parser_and_generator/mod.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ use rspack_cacheable::{cacheable, cacheable_dyn};
77
use rspack_core::diagnostics::map_box_diagnostics_to_module_parse_diagnostics;
88
use rspack_core::rspack_sources::{BoxSource, ReplaceSource, Source, SourceExt};
99
use rspack_core::{
10-
render_init_fragments, AsyncDependenciesBlockIdentifier, BuildMetaExportsType, ChunkGraph,
11-
Compilation, DependenciesBlock, DependencyId, DependencyRange, GenerateContext, Module,
12-
ModuleGraph, ModuleType, ParseContext, ParseResult, ParserAndGenerator, SideEffectsBailoutItem,
13-
SourceType, TemplateContext, TemplateReplaceSource,
10+
remove_bom, render_init_fragments, AsyncDependenciesBlockIdentifier, BuildMetaExportsType,
11+
ChunkGraph, Compilation, DependenciesBlock, DependencyId, DependencyRange, GenerateContext,
12+
Module, ModuleGraph, ModuleType, ParseContext, ParseResult, ParserAndGenerator,
13+
SideEffectsBailoutItem, SourceType, TemplateContext, TemplateReplaceSource,
1414
};
1515
use rspack_error::miette::Diagnostic;
1616
use rspack_error::{DiagnosticExt, IntoTWithDiagnosticArray, Result, TWithDiagnosticArray};
@@ -344,13 +344,3 @@ impl ParserAndGenerator for JavaScriptParserAndGenerator {
344344
None
345345
}
346346
}
347-
348-
fn remove_bom(s: Arc<dyn Source>) -> Arc<dyn Source> {
349-
if s.source().starts_with('\u{feff}') {
350-
let mut s = ReplaceSource::new(s);
351-
s.replace(0, 3, "", None);
352-
s.boxed()
353-
} else {
354-
s
355-
}
356-
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.c {
2+
color: pink;
3+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import "./index.css";
2+
3+
it("should not contain BOM at the start of the CSS file", async () => {
4+
const fs = __non_webpack_require__("fs");
5+
const path = __non_webpack_require__("path");
6+
const css = await fs.promises.readFile(
7+
path.resolve(__dirname, "bundle0.css"),
8+
"utf-8"
9+
);
10+
expect(css[0]).not.toBe("\uFEFF");
11+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/** @type {import("@rspack/core").Configuration} */
2+
module.exports = {
3+
target: "web",
4+
node: false,
5+
entry: {
6+
main: "./index.js"
7+
},
8+
experiments: {
9+
css: true
10+
}
11+
};

0 commit comments

Comments
 (0)