rspack_plugin_extract_css/
parser_plugin.rs1use rspack_core::{BoxDependency, DependencyRange};
2use rspack_plugin_javascript::{JavascriptParserPlugin, visitors::JavascriptParser};
3use rspack_util::fx_hash::FxDashMap;
4use serde::Deserialize;
5
6use crate::{css_dependency::CssDependency, plugin::PLUGIN_NAME};
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct CssExtractJsonData {
11 pub identifier: String,
12 pub content: String,
13 pub context: String,
14 pub media: Option<String>,
15 pub supports: Option<String>,
16 pub source_map: Option<String>,
17 pub identifier_index: u32,
18 pub layer: Option<String>,
19}
20
21#[derive(Debug, Default)]
22pub struct PluginCssExtractParserPlugin {
23 cache: FxDashMap<String, Vec<BoxDependency>>,
24}
25
26impl JavascriptParserPlugin for PluginCssExtractParserPlugin {
27 fn finish(&self, parser: &mut JavascriptParser) -> Option<bool> {
28 let deps = if let Some(data_str) = parser.parse_meta.remove(PLUGIN_NAME)
29 && let Ok(data_str) = (data_str as Box<dyn std::any::Any>)
30 .downcast::<String>()
31 .map(|i| *i)
32 {
33 if let Some(deps) = self.cache.get(&data_str) {
34 deps.clone()
35 } else if let Ok(data) = serde_json::from_str::<Vec<CssExtractJsonData>>(&data_str) {
36 let deps = data
37 .iter()
38 .enumerate()
39 .map(
40 |(
41 index,
42 CssExtractJsonData {
43 identifier,
44 content,
45 context,
46 media,
47 supports,
48 source_map,
49 identifier_index,
50 layer,
51 },
52 )| {
53 Box::new(CssDependency::new(
54 identifier.into(),
55 parser.get_module_layer().cloned(),
56 layer.clone(),
57 content.clone(),
58 context.clone(),
59 media.clone(),
60 supports.clone(),
61 source_map.clone(),
62 *identifier_index,
63 DependencyRange::new(index as u32, (index + 1) as u32),
64 parser.build_info.cacheable,
65 parser.build_info.file_dependencies.clone(),
66 parser.build_info.context_dependencies.clone(),
67 parser.build_info.missing_dependencies.clone(),
68 parser.build_info.build_dependencies.clone(),
69 )) as BoxDependency
70 },
71 )
72 .collect::<Vec<_>>();
73 self.cache.insert(data_str, deps.clone());
74 parser.build_info.strict = true;
75 deps
76 } else {
77 vec![]
78 }
79 } else {
80 vec![]
81 };
82 parser.add_dependencies(deps);
83 None
84 }
85}