From 250304a50fe101dba3f2450fb3bd9d5037047a67 Mon Sep 17 00:00:00 2001 From: harpsealjs Date: Thu, 15 Aug 2024 13:25:37 +0800 Subject: [PATCH] feat!: improve HtmlRspackPlugin (#7577) --- Cargo.lock | 1 + crates/node_binding/binding.d.ts | 13 +- .../src/options/raw_builtins/raw_html.rs | 32 +- crates/rspack_plugin_html/Cargo.toml | 1 + crates/rspack_plugin_html/src/config.rs | 23 +- crates/rspack_plugin_html/src/parser.rs | 16 +- crates/rspack_plugin_html/src/plugin.rs | 95 +- .../rspack_plugin_html/src/visitors/asset.rs | 80 +- crates/rspack_plugin_html/src/visitors/mod.rs | 2 +- .../rspack_plugin_html/src/visitors/utils.rs | 25 + .../basic/__snapshots__/output.snap.txt | 10 +- .../chunks/__snapshots__/output.snap.txt | 13 +- .../plugin-html/chunks/rspack.config.js | 2 +- .../favicon/__snapshots__/output.snap.txt | 10 +- .../filename/__snapshots__/output.snap.txt | 23 +- .../inject/__snapshots__/output.snap.txt | 30 +- .../meta/__snapshots__/output.snap.txt | 10 +- .../minify/__snapshots__/output.snap.txt | 2 +- .../mpa/__snapshots__/output.snap.txt | 39 +- .../public-path/__snapshots__/output.snap.txt | 10 +- .../__snapshots__/output.snap.txt | 12 +- .../__snapshots__/output.snap.txt | 4 +- .../title/__snapshots__/output.snap.txt | 10 +- .../variant/__snapshots__/output.snap.txt | 13 +- .../html-favicon-absolute-publicpath/index.js | 4 +- .../index.js | 4 +- .../html-favicon-absolute-subdir/index.js | 4 +- .../builtins/html-favicon-absolute/index.js | 4 +- .../html-favicon-relative-publicpath/index.js | 4 +- .../index.js | 4 +- .../html-favicon-relative-subdir/index.js | 4 +- .../builtins/html-favicon-relative/index.js | 4 +- .../configCases/builtins/html-meta/index.js | 8 +- .../builtins/html_syntax_error/stats.err | 9 +- packages/rspack/etc/api.md | 51 +- .../src/builtin-plugin/HtmlRspackPlugin.ts | 22 +- tests/plugin-test/html-plugin/basic.test.js | 1084 ++++++++--------- .../en/plugins/rspack/html-rspack-plugin.mdx | 4 +- .../zh/plugins/rspack/html-rspack-plugin.mdx | 4 +- 39 files changed, 868 insertions(+), 822 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc00bd24bb92..e62f5f6830f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3628,6 +3628,7 @@ dependencies = [ "swc_html", "swc_html_minifier", "tracing", + "urlencoding", ] [[package]] diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 883f67afbaf1..e7557595454f 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -1229,6 +1229,11 @@ export interface RawGeneratorOptions { cssModule?: RawCssModuleGeneratorOptions } +export interface RawHtmlRspackPluginBaseOptions { + href?: string + target?: "_self" | "_blank" | "_parent" | "_top" +} + export interface RawHtmlRspackPluginOptions { /** emitted file name in output path */ filename?: string @@ -1240,16 +1245,18 @@ export interface RawHtmlRspackPluginOptions { inject: "head" | "body" | "false" /** path or `auto` */ publicPath?: string - /** `blocking`, `defer`, or `module` */ - scriptLoading: "blocking" | "defer" | "module" + /** `blocking`, `defer`, `module` or `systemjs-module` */ + scriptLoading: "blocking" | "defer" | "module" | "systemjs-module" /** entry_chunk_name (only entry chunks are supported) */ chunks?: Array - excludedChunks?: Array + excludeChunks?: Array sri?: "sha256" | "sha384" | "sha512" minify?: boolean title?: string favicon?: string meta?: Record> + hash?: boolean + base?: RawHtmlRspackPluginBaseOptions } export interface RawHttpExternalsRspackPluginOptions { diff --git a/crates/rspack_binding_options/src/options/raw_builtins/raw_html.rs b/crates/rspack_binding_options/src/options/raw_builtins/raw_html.rs index 51ac3b92dc9a..964535961120 100644 --- a/crates/rspack_binding_options/src/options/raw_builtins/raw_html.rs +++ b/crates/rspack_binding_options/src/options/raw_builtins/raw_html.rs @@ -3,6 +3,7 @@ use std::str::FromStr; use napi_derive::napi; use rspack_plugin_html::config::HtmlInject; +use rspack_plugin_html::config::HtmlRspackPluginBaseOptions; use rspack_plugin_html::config::HtmlRspackPluginOptions; use rspack_plugin_html::config::HtmlScriptLoading; use rspack_plugin_html::sri::HtmlSriHashFunction; @@ -27,19 +28,21 @@ pub struct RawHtmlRspackPluginOptions { pub inject: RawHtmlInject, /// path or `auto` pub public_path: Option, - /// `blocking`, `defer`, or `module` - #[napi(ts_type = "\"blocking\" | \"defer\" | \"module\"")] + /// `blocking`, `defer`, `module` or `systemjs-module` + #[napi(ts_type = "\"blocking\" | \"defer\" | \"module\" | \"systemjs-module\"")] pub script_loading: RawHtmlScriptLoading, /// entry_chunk_name (only entry chunks are supported) pub chunks: Option>, - pub excluded_chunks: Option>, + pub exclude_chunks: Option>, #[napi(ts_type = "\"sha256\" | \"sha384\" | \"sha512\"")] pub sri: Option, pub minify: Option, pub title: Option, pub favicon: Option, pub meta: Option>>, + pub hash: Option, + pub base: Option, } impl From for HtmlRspackPluginOptions { @@ -62,12 +65,31 @@ impl From for HtmlRspackPluginOptions { public_path: value.public_path, script_loading, chunks: value.chunks, - excluded_chunks: value.excluded_chunks, + exclude_chunks: value.exclude_chunks, sri, - minify: value.minify.unwrap_or_default(), + minify: value.minify, title: value.title, favicon: value.favicon, meta: value.meta, + hash: value.hash, + base: value.base.map(|v| v.into()), + } + } +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawHtmlRspackPluginBaseOptions { + pub href: Option, + #[napi(ts_type = "\"_self\" | \"_blank\" | \"_parent\" | \"_top\"")] + pub target: Option, +} + +impl From for HtmlRspackPluginBaseOptions { + fn from(value: RawHtmlRspackPluginBaseOptions) -> Self { + HtmlRspackPluginBaseOptions { + href: value.href, + target: value.target, } } } diff --git a/crates/rspack_plugin_html/Cargo.toml b/crates/rspack_plugin_html/Cargo.toml index 8f8d942c388b..92dd1accc416 100644 --- a/crates/rspack_plugin_html/Cargo.toml +++ b/crates/rspack_plugin_html/Cargo.toml @@ -30,6 +30,7 @@ swc_core = { workspace = true } swc_html = { workspace = true } swc_html_minifier = { workspace = true } tracing = { workspace = true } +urlencoding = { workspace = true } [package.metadata.cargo-shear] ignored = ["tracing"] diff --git a/crates/rspack_plugin_html/src/config.rs b/crates/rspack_plugin_html/src/config.rs index f5892bda760f..5af976aa01ab 100644 --- a/crates/rspack_plugin_html/src/config.rs +++ b/crates/rspack_plugin_html/src/config.rs @@ -42,6 +42,7 @@ pub enum HtmlScriptLoading { Blocking, Defer, Module, + SystemjsModule, } impl FromStr for HtmlScriptLoading { @@ -54,6 +55,8 @@ impl FromStr for HtmlScriptLoading { Ok(HtmlScriptLoading::Defer) } else if s.eq("module") { Ok(HtmlScriptLoading::Module) + } else if s.eq("systemjs-module") { + Ok(HtmlScriptLoading::SystemjsModule) } else { Err(anyhow::Error::msg( "scriptLoading in html config only support 'blocking', 'defer' or 'module'", @@ -62,6 +65,14 @@ impl FromStr for HtmlScriptLoading { } } +#[cfg_attr(feature = "testing", derive(JsonSchema))] +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct HtmlRspackPluginBaseOptions { + pub href: Option, + pub target: Option, +} + #[cfg_attr(feature = "testing", derive(JsonSchema))] #[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase", deny_unknown_fields)] @@ -84,16 +95,18 @@ pub struct HtmlRspackPluginOptions { /// entry_chunk_name (only entry chunks are supported) pub chunks: Option>, - pub excluded_chunks: Option>, + pub exclude_chunks: Option>, /// hash func that used in subsource integrity /// sha384, sha256 or sha512 pub sri: Option, #[serde(default)] - pub minify: bool, + pub minify: Option, pub title: Option, pub favicon: Option, pub meta: Option>>, + pub hash: Option, + pub base: Option, } fn default_filename() -> String { @@ -119,12 +132,14 @@ impl Default for HtmlRspackPluginOptions { public_path: None, script_loading: default_script_loading(), chunks: None, - excluded_chunks: None, + exclude_chunks: None, sri: None, - minify: false, + minify: None, title: None, favicon: None, meta: None, + hash: None, + base: None, } } } diff --git a/crates/rspack_plugin_html/src/parser.rs b/crates/rspack_plugin_html/src/parser.rs index 927e419f3b00..8bfc553da55c 100644 --- a/crates/rspack_plugin_html/src/parser.rs +++ b/crates/rspack_plugin_html/src/parser.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use rspack_core::ErrorSpan; +use rspack_core::{Compilation, ErrorSpan}; use rspack_error::{error, DiagnosticKind, IntoTWithDiagnosticArray, Result, TWithDiagnosticArray}; use swc_core::common::{sync::Lrc, FileName, FilePathMapping, SourceFile, SourceMap, GLOBALS}; use swc_html::{ @@ -27,7 +27,7 @@ impl<'a> HtmlCompiler<'a> { pub fn parse_file(&self, path: &str, source: String) -> Result> { let cm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fm = cm.new_source_file(Arc::new(FileName::Custom(path.to_string())), source); + let fm = cm.new_source_file(Arc::new(FileName::Custom(path.to_string())), source.clone()); let mut errors = vec![]; let document = parse_file_as_document(fm.as_ref(), ParserConfig::default(), &mut errors); @@ -40,13 +40,19 @@ impl<'a> HtmlCompiler<'a> { .map_err(|e| html_parse_error_to_traceable_error(e, &fm)) } - pub fn codegen(&self, ast: &mut Document) -> Result { + pub fn codegen(&self, ast: &mut Document, compilation: &Compilation) -> Result { let writer_config = BasicHtmlWriterConfig::default(); + let minify = self.config.minify.unwrap_or(matches!( + compilation.options.mode, + rspack_core::Mode::Production + )); let codegen_config = CodegenConfig { - minify: self.config.minify, + minify, + quotes: Some(true), + tag_omission: Some(false), ..Default::default() }; - if self.config.minify { + if minify { // Minify can't leak to user land because it doesn't implement `ToNapiValue` Trait GLOBALS.set(&Default::default(), || { minify_document(ast, &MinifyOptions::default()); diff --git a/crates/rspack_plugin_html/src/plugin.rs b/crates/rspack_plugin_html/src/plugin.rs index 63baaf380e6b..ccd74de74127 100644 --- a/crates/rspack_plugin_html/src/plugin.rs +++ b/crates/rspack_plugin_html/src/plugin.rs @@ -7,6 +7,7 @@ use std::{ use anyhow::Context; use dojang::dojang::Dojang; +use itertools::Itertools; use rayon::prelude::*; use rspack_core::{ parse_to_url, @@ -22,7 +23,10 @@ use crate::{ config::{HtmlInject, HtmlRspackPluginOptions}, parser::HtmlCompiler, sri::{add_sri, create_digest_from_asset}, - visitors::asset::{AssetWriter, HTMLPluginTag}, + visitors::{ + asset::{AssetWriter, HTMLPluginTag}, + utils::{append_hash, generate_posix_path}, + }, }; #[plugin] @@ -75,7 +79,7 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { }; // process with template parameters - let template_result = if let Some(template_parameters) = &self.config.template_parameters { + let mut template_result = if let Some(template_parameters) = &self.config.template_parameters { let mut dj = Dojang::new(); dj.add(url.clone(), content) .expect("failed to add template"); @@ -85,6 +89,11 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { content }; + let has_doctype = template_result.contains("!DOCTYPE") || template_result.contains("!doctype"); + if !has_doctype { + template_result = format!("{template_result}"); + } + let ast_with_diagnostic = parser.parse_file(&url, template_result)?; let (mut current_ast, diagnostic) = ast_with_diagnostic.split_into_parts(); @@ -100,8 +109,8 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { if let Some(included_chunks) = &config.chunks { included = included_chunks.iter().any(|c| c.eq(entry_name)); } - if let Some(excluded_chunks) = &config.excluded_chunks { - included = included && !excluded_chunks.iter().any(|c| c.eq(entry_name)); + if let Some(exclude_chunks) = &config.exclude_chunks { + included = included && !exclude_chunks.iter().any(|c| c.eq(entry_name)); } included }) @@ -121,17 +130,28 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { // if inject is 'false', don't do anything if !matches!(config.inject, HtmlInject::False) { for (asset_name, asset) in included_assets { - if let Some(extension) = Path::new(&asset_name).extension() { - let asset_uri = format!( - "{}{asset_name}", + if let Some(extension) = + Path::new(asset_name.split("?").next().unwrap_or_default()).extension() + { + let mut asset_uri = format!( + "{}{}", config.get_public_path(compilation, &self.config.filename), + url_encode_path(&asset_name) ); + if config.hash.unwrap_or_default() { + if let Some(hash) = compilation.get_hash() { + asset_uri = append_hash(&asset_uri, hash); + } + } let mut tag: Option = None; if extension.eq_ignore_ascii_case("css") { - tag = Some(HTMLPluginTag::create_style(&asset_uri, HtmlInject::Head)); + tag = Some(HTMLPluginTag::create_style( + &generate_posix_path(&asset_uri), + HtmlInject::Head, + )); } else if extension.eq_ignore_ascii_case("js") || extension.eq_ignore_ascii_case("mjs") { tag = Some(HTMLPluginTag::create_script( - &asset_uri, + &generate_posix_path(&asset_uri), config.inject, &config.script_loading, )) @@ -157,18 +177,39 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { } let tags = tags.into_iter().map(|(tag, _)| tag).collect::>(); - let mut visitor = AssetWriter::new(config, &tags, compilation); - current_ast.visit_mut_with(&mut visitor); - - let source = parser.codegen(&mut current_ast)?; - let hash = hash_for_source(&source); - let html_file_name = FilenameTemplate::from(config.filename.clone()); // Use the same filename as template let output_path = compilation .options .output .path .join(normalized_template_name); + + let html_file_name = FilenameTemplate::from( + config + .filename + .replace("[templatehash]", "[contenthash]") + .clone(), + ); + // use to calculate relative favicon path when no publicPath + let fake_html_file_name = compilation + .get_path( + &html_file_name, + PathData::default().filename(&output_path.to_string_lossy()), + ) + .always_ok(); + + let mut visitor = AssetWriter::new(config, &tags, compilation, &fake_html_file_name); + current_ast.visit_mut_with(&mut visitor); + + let mut source = parser + .codegen(&mut current_ast, compilation)? + .replace("$$RSPACK_URL_AMP$$", "&"); + + if !has_doctype { + source = source.replace("", ""); + } + let hash = hash_for_source(&source); + let (output_path, asset_info) = compilation .get_path_with_info( &html_file_name, @@ -243,3 +284,27 @@ fn hash_for_source(source: &str) -> String { source.hash(&mut hasher); format!("{:016x}", hasher.finish()) } + +fn url_encode_path(file_path: &str) -> String { + let query_string_start = file_path.find('?'); + let url_path = if let Some(query_string_start) = query_string_start { + &file_path[..query_string_start] + } else { + file_path + }; + let query_string = if let Some(query_string_start) = query_string_start { + &file_path[query_string_start..] + } else { + "" + }; + + format!( + "{}{}", + url_path + .split('/') + .map(|p| { urlencoding::encode(p) }) + .join("/"), + // element.outerHTML will escape '&' so need to add a placeholder here + query_string.replace("&", "$$RSPACK_URL_AMP$$") + ) +} diff --git a/crates/rspack_plugin_html/src/visitors/asset.rs b/crates/rspack_plugin_html/src/visitors/asset.rs index d517f0ac5a89..15317046ac75 100644 --- a/crates/rspack_plugin_html/src/visitors/asset.rs +++ b/crates/rspack_plugin_html/src/visitors/asset.rs @@ -1,14 +1,13 @@ -use std::env; use std::path::PathBuf; use itertools::Itertools; -use regex::Regex; use rspack_core::Compilation; +use sugar_path::SugarPath; use swc_core::{common::DUMMY_SP, ecma::atoms::Atom}; use swc_html::ast::{Attribute, Child, Element, Namespace, Text}; use swc_html::visit::{VisitMut, VisitMutWith}; -use super::utils::create_element; +use super::utils::{append_hash, create_element, generate_posix_path}; use crate::config::{HtmlInject, HtmlRspackPluginOptions, HtmlScriptLoading}; // the tag @@ -59,6 +58,12 @@ impl HTMLPluginTag { attr_value: Some("module".to_string()), }); } + HtmlScriptLoading::SystemjsModule => { + attributes.push(HtmlPluginAttribute { + attr_name: "type".to_string(), + attr_value: Some("systemjs-module".to_string()), + }); + } _ => {} } @@ -91,6 +96,7 @@ pub struct AssetWriter<'a, 'c> { head_tags: Vec<&'a HTMLPluginTag>, body_tags: Vec<&'a HTMLPluginTag>, compilation: &'c Compilation, + html_path: &'a str, } impl<'a, 'c> AssetWriter<'a, 'c> { @@ -98,6 +104,7 @@ impl<'a, 'c> AssetWriter<'a, 'c> { config: &'a HtmlRspackPluginOptions, tags: &'a [HTMLPluginTag], compilation: &'c Compilation, + html_path: &'a str, ) -> AssetWriter<'a, 'c> { let mut head_tags: Vec<&HTMLPluginTag> = vec![]; let mut body_tags: Vec<&HTMLPluginTag> = vec![]; @@ -117,6 +124,7 @@ impl<'a, 'c> AssetWriter<'a, 'c> { head_tags, body_tags, compilation, + html_path, } } } @@ -160,7 +168,48 @@ impl VisitMut for AssetWriter<'_, '_> { } } - // add favicon + // add basic tag + if let Some(base) = &self.config.base { + let mut attributes = vec![]; + + if let Some(href) = &base.href { + attributes.push(Attribute { + span: Default::default(), + namespace: None, + prefix: None, + name: "href".into(), + raw_name: None, + value: Some(href.to_string().into()), + raw_value: None, + }); + } + + if let Some(target) = &base.target { + attributes.push(Attribute { + span: Default::default(), + namespace: None, + prefix: None, + name: "target".into(), + raw_name: None, + value: Some(target.to_string().into()), + raw_value: None, + }); + } + + if !attributes.is_empty() { + n.children.push(Child::Element(Element { + tag_name: Atom::from("base"), + children: vec![], + is_self_closing: true, + namespace: Namespace::HTML, + span: DUMMY_SP, + attributes, + content: None, + })); + } + } + + // add favicon link if let Some(favicon) = &self.config.favicon { let favicon = PathBuf::from(favicon) .file_name() @@ -171,18 +220,29 @@ impl VisitMut for AssetWriter<'_, '_> { let favicon_relative_path = PathBuf::from(self.config.get_relative_path(self.compilation, &favicon)); - let mut favicon_path = PathBuf::from(self.config.get_public_path( + let mut favicon_path: PathBuf = PathBuf::from(self.config.get_public_path( self.compilation, favicon_relative_path.to_string_lossy().to_string().as_str(), )); - favicon_path.push(favicon_relative_path); + if favicon_path.to_str().unwrap_or_default().is_empty() { + favicon_path = self + .compilation + .options + .output + .path + .join(favicon_relative_path) + .relative(PathBuf::from(self.html_path).join("..")); + } else { + favicon_path.push(favicon_relative_path); + } let mut favicon_link_path = favicon_path.to_string_lossy().to_string(); - if env::consts::OS == "windows" { - let reg = Regex::new(r"[/\\]").expect("Invalid RegExp"); - favicon_link_path = reg.replace_all(favicon_link_path.as_str(), "/").to_string(); + if self.config.hash.unwrap_or_default() { + if let Some(hash) = self.compilation.get_hash() { + favicon_link_path = append_hash(&favicon_link_path, hash); + } } n.children.push(Child::Element(Element { @@ -207,7 +267,7 @@ impl VisitMut for AssetWriter<'_, '_> { prefix: None, name: "href".into(), raw_name: None, - value: Some(favicon_link_path.into()), + value: Some(generate_posix_path(&favicon_link_path).into()), raw_value: None, }, ], diff --git a/crates/rspack_plugin_html/src/visitors/mod.rs b/crates/rspack_plugin_html/src/visitors/mod.rs index 2313b1338e9a..18daee552353 100644 --- a/crates/rspack_plugin_html/src/visitors/mod.rs +++ b/crates/rspack_plugin_html/src/visitors/mod.rs @@ -1,2 +1,2 @@ pub mod asset; -mod utils; +pub mod utils; diff --git a/crates/rspack_plugin_html/src/visitors/utils.rs b/crates/rspack_plugin_html/src/visitors/utils.rs index 93274d7ee6f2..bb1540e35045 100644 --- a/crates/rspack_plugin_html/src/visitors/utils.rs +++ b/crates/rspack_plugin_html/src/visitors/utils.rs @@ -1,3 +1,6 @@ +use std::{borrow::Cow, env}; + +use regex::Regex; use swc_core::{common::DUMMY_SP, ecma::atoms::Atom}; use swc_html::ast::{Attribute, Element, Namespace}; @@ -33,3 +36,25 @@ pub fn create_element(tag: &HTMLPluginTag) -> Element { span: DUMMY_SP, } } + +pub fn append_hash(url: &str, hash: &str) -> String { + format!( + "{}{}{}", + url, + if url.contains("?") { + "$$RSPACK_URL_AMP$$" + } else { + "?" + }, + hash + ) +} + +pub fn generate_posix_path(path: &str) -> Cow<'_, str> { + if env::consts::OS == "windows" { + let reg = Regex::new(r"[/\\]").expect("Invalid RegExp"); + reg.replace_all(path, "/") + } else { + path.into() + } +} diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/basic/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/basic/__snapshots__/output.snap.txt index 7ecc6b569cd0..07287fce8795 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/basic/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/basic/__snapshots__/output.snap.txt @@ -1,11 +1,3 @@ ```html title=index.html - - - - - rspack - - - - +rspack ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/chunks/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/chunks/__snapshots__/output.snap.txt index e1ca79897cb8..1c58cc70e1e4 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/chunks/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/chunks/__snapshots__/output.snap.txt @@ -1,14 +1,3 @@ ```html title=index.html - - - - - Rspack App - - - - - - - +Rspack App ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/chunks/rspack.config.js b/packages/rspack-test-tools/tests/builtinCases/plugin-html/chunks/rspack.config.js index 0df7838d3549..cab21ce74364 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/chunks/rspack.config.js +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/chunks/rspack.config.js @@ -16,7 +16,7 @@ module.exports = { { template: "index.html", chunks: ["chunk1", "chunk2"], - excludedChunks: ["chunk2"] + excludeChunks: ["chunk2"] } ] } diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/favicon/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/favicon/__snapshots__/output.snap.txt index 099e49a63515..9475815f7ede 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/favicon/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/favicon/__snapshots__/output.snap.txt @@ -1,11 +1,3 @@ ```html title=index.html - - - - - rspack - - - - +rspack ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/filename/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/filename/__snapshots__/output.snap.txt index f6376ba85532..3d810ef18cdc 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/filename/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/filename/__snapshots__/output.snap.txt @@ -1,26 +1,7 @@ ```html title=default.28094d62af6f500a.html - - - - - rspack - - - - +rspack ``` ```html title=index.28094d62af6f500a.html - - - - - Rspack App - - - - - - - +Rspack App ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/inject/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/inject/__snapshots__/output.snap.txt index 87a5eaefebb4..5c345196d3a4 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/inject/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/inject/__snapshots__/output.snap.txt @@ -1,35 +1,11 @@ ```html title=inject_body.html - - - - - rspack - - - - +rspack ``` ```html title=inject_false.html - - - - - rspack - - - - +rspack ``` ```html title=inject_head.html - - - - - rspack - - - - +rspack ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/meta/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/meta/__snapshots__/output.snap.txt index 95cf917d4979..10bbe1b08817 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/meta/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/meta/__snapshots__/output.snap.txt @@ -1,11 +1,3 @@ ```html title=index.html - - - - - rspack - - - - +rspack ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/minify/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/minify/__snapshots__/output.snap.txt index 6e139cbd7eb3..e49a0794e93f 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/minify/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/minify/__snapshots__/output.snap.txt @@ -1,3 +1,3 @@ ```html title=index.html -rspack +rspack ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/mpa/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/mpa/__snapshots__/output.snap.txt index 3d4eb09c602d..db8e70525a66 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/mpa/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/mpa/__snapshots__/output.snap.txt @@ -1,44 +1,11 @@ ```html title=chunk1.html - - - - - Rspack App - - - - - - - +Rspack App ``` ```html title=chunk2.html - - - - - Rspack App - - - - - - - +Rspack App ``` ```html title=chunk3.html - - - - - Rspack App - - - - - - - +Rspack App ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/public-path/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/public-path/__snapshots__/output.snap.txt index 3dda21ac0592..c62ab016f55f 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/public-path/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/public-path/__snapshots__/output.snap.txt @@ -1,11 +1,3 @@ ```html title=index.html - - - - - rspack - - - - +rspack ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/template+templateParameters/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/template+templateParameters/__snapshots__/output.snap.txt index 27e173188a5f..ec4ae71af905 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/template+templateParameters/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/template+templateParameters/__snapshots__/output.snap.txt @@ -1,13 +1,3 @@ ```html title=index.html - - - - - bar - - - - - - +bar ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/templateContent+templateParameters/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/templateContent+templateParameters/__snapshots__/output.snap.txt index 910ed6aae495..f3c66651d4c8 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/templateContent+templateParameters/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/templateContent+templateParameters/__snapshots__/output.snap.txt @@ -1,5 +1,3 @@ ```html title=index.html - - -
bar
+
bar
``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/title/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/title/__snapshots__/output.snap.txt index 471e9b071ed9..b200b1d9c06b 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/title/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/title/__snapshots__/output.snap.txt @@ -1,11 +1,3 @@ ```html title=index.html - - - - - Rspack title - - - - +Rspack title ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/builtinCases/plugin-html/variant/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/plugin-html/variant/__snapshots__/output.snap.txt index adeefba195a0..23cf29d059bc 100644 --- a/packages/rspack-test-tools/tests/builtinCases/plugin-html/variant/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/plugin-html/variant/__snapshots__/output.snap.txt @@ -1,14 +1,3 @@ ```html title=output.html - - - - - Rspack App - - - - - - - +Rspack App ``` \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath/index.js b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath/index.js index b20432fd3df2..59d03916a04e 100644 --- a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath/index.js +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-publicpath/index.js @@ -7,7 +7,5 @@ it("html favicon with absolute path and public path", () => { const htmlPath = path.join(__dirname, "./index.html"); const htmlContent = fs.readFileSync(htmlPath, "utf-8"); - expect( - htmlContent.includes('') - ).toBe(true); + expect(htmlContent).toContain(''); }); diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-subdir-publicpath/index.js b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-subdir-publicpath/index.js index b20432fd3df2..59d03916a04e 100644 --- a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-subdir-publicpath/index.js +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-subdir-publicpath/index.js @@ -7,7 +7,5 @@ it("html favicon with absolute path and public path", () => { const htmlPath = path.join(__dirname, "./index.html"); const htmlContent = fs.readFileSync(htmlPath, "utf-8"); - expect( - htmlContent.includes('') - ).toBe(true); + expect(htmlContent).toContain(''); }); diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-subdir/index.js b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-subdir/index.js index 99cca1a25047..010fa701ed1a 100644 --- a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-subdir/index.js +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute-subdir/index.js @@ -7,7 +7,5 @@ it("html favicon with absolute path in subdirectory", () => { const htmlPath = path.join(__dirname, "./index.html"); const htmlContent = fs.readFileSync(htmlPath, "utf-8"); - expect( - htmlContent.includes('') - ).toBe(true); + expect(htmlContent).toContain(''); }); diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute/index.js b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute/index.js index b1cf204ee59e..b7c2416e0555 100644 --- a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute/index.js +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-absolute/index.js @@ -7,7 +7,5 @@ it("html favicon with absolute path", () => { const htmlPath = path.join(__dirname, "./index.html"); const htmlContent = fs.readFileSync(htmlPath, "utf-8"); - expect(htmlContent.includes('')).toBe( - true - ); + expect(htmlContent).toContain(''); }); diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath/index.js b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath/index.js index b20432fd3df2..59d03916a04e 100644 --- a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath/index.js +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-publicpath/index.js @@ -7,7 +7,5 @@ it("html favicon with absolute path and public path", () => { const htmlPath = path.join(__dirname, "./index.html"); const htmlContent = fs.readFileSync(htmlPath, "utf-8"); - expect( - htmlContent.includes('') - ).toBe(true); + expect(htmlContent).toContain(''); }); diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-subdir-publicpath/index.js b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-subdir-publicpath/index.js index b20432fd3df2..59d03916a04e 100644 --- a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-subdir-publicpath/index.js +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-subdir-publicpath/index.js @@ -7,7 +7,5 @@ it("html favicon with absolute path and public path", () => { const htmlPath = path.join(__dirname, "./index.html"); const htmlContent = fs.readFileSync(htmlPath, "utf-8"); - expect( - htmlContent.includes('') - ).toBe(true); + expect(htmlContent).toContain(''); }); diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-subdir/index.js b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-subdir/index.js index 99cca1a25047..010fa701ed1a 100644 --- a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-subdir/index.js +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative-subdir/index.js @@ -7,7 +7,5 @@ it("html favicon with absolute path in subdirectory", () => { const htmlPath = path.join(__dirname, "./index.html"); const htmlContent = fs.readFileSync(htmlPath, "utf-8"); - expect( - htmlContent.includes('') - ).toBe(true); + expect(htmlContent).toContain(''); }); diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative/index.js b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative/index.js index b1cf204ee59e..b7c2416e0555 100644 --- a/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative/index.js +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-favicon-relative/index.js @@ -7,7 +7,5 @@ it("html favicon with absolute path", () => { const htmlPath = path.join(__dirname, "./index.html"); const htmlContent = fs.readFileSync(htmlPath, "utf-8"); - expect(htmlContent.includes('')).toBe( - true - ); + expect(htmlContent).toContain(''); }); diff --git a/packages/rspack-test-tools/tests/configCases/builtins/html-meta/index.js b/packages/rspack-test-tools/tests/configCases/builtins/html-meta/index.js index dc1c787de132..8ae6eef5e8c5 100644 --- a/packages/rspack-test-tools/tests/configCases/builtins/html-meta/index.js +++ b/packages/rspack-test-tools/tests/configCases/builtins/html-meta/index.js @@ -4,10 +4,6 @@ const path = require("path"); it("html meta", () => { const htmlPath = path.join(__dirname, "./index.html"); const htmlContent = fs.readFileSync(htmlPath, "utf-8"); - expect( - htmlContent.includes( - '' - ) - ).toBe(true); - expect(htmlContent.includes('')).toBe(true); + expect(htmlContent).toContain(''); + expect(htmlContent).toContain(''); }); diff --git a/packages/rspack-test-tools/tests/diagnosticsCases/builtins/html_syntax_error/stats.err b/packages/rspack-test-tools/tests/diagnosticsCases/builtins/html_syntax_error/stats.err index 486237994f34..660d87ea161b 100644 --- a/packages/rspack-test-tools/tests/diagnosticsCases/builtins/html_syntax_error/stats.err +++ b/packages/rspack-test-tools/tests/diagnosticsCases/builtins/html_syntax_error/stats.err @@ -1,13 +1,6 @@ -ERROR in × HTML parsing error: Start tag seen without seeing a doctype first, expected "" - ╭─[1:0] - 1 │ - · ────── - 2 │ - ╰──── - ERROR in × HTML parsing error: Stray end tag "something" ╭─[2:2] - 1 │ + 1 │ 2 │ · ──────────── ╰──── \ No newline at end of file diff --git a/packages/rspack/etc/api.md b/packages/rspack/etc/api.md index a6895a2cdbc5..6464b7e4b136 100644 --- a/packages/rspack/etc/api.md +++ b/packages/rspack/etc/api.md @@ -4587,13 +4587,18 @@ export const HtmlRspackPlugin: { new (c?: { filename?: string | undefined; publicPath?: string | undefined; + hash?: boolean | undefined; chunks?: string[] | undefined; template?: string | undefined; templateContent?: string | undefined; templateParameters?: Record | undefined; inject?: boolean | "head" | "body" | undefined; - scriptLoading?: "module" | "blocking" | "defer" | undefined; - excludedChunks?: string[] | undefined; + base?: string | { + target?: "_self" | "_blank" | "_parent" | "_top" | undefined; + href?: string | undefined; + } | undefined; + scriptLoading?: "module" | "blocking" | "defer" | "systemjs-module" | undefined; + excludeChunks?: string[] | undefined; sri?: "sha256" | "sha384" | "sha512" | undefined; minify?: boolean | undefined; title?: string | undefined; @@ -4604,13 +4609,18 @@ export const HtmlRspackPlugin: { _args: [c?: { filename?: string | undefined; publicPath?: string | undefined; + hash?: boolean | undefined; chunks?: string[] | undefined; template?: string | undefined; templateContent?: string | undefined; templateParameters?: Record | undefined; inject?: boolean | "head" | "body" | undefined; - scriptLoading?: "module" | "blocking" | "defer" | undefined; - excludedChunks?: string[] | undefined; + base?: string | { + target?: "_self" | "_blank" | "_parent" | "_top" | undefined; + href?: string | undefined; + } | undefined; + scriptLoading?: "module" | "blocking" | "defer" | "systemjs-module" | undefined; + excludeChunks?: string[] | undefined; sri?: "sha256" | "sha384" | "sha512" | undefined; minify?: boolean | undefined; title?: string | undefined; @@ -4634,24 +4644,40 @@ const htmlRspackPluginOptions: z.ZodObject<{ templateParameters: z.ZodOptional>; inject: z.ZodOptional, z.ZodBoolean]>>; publicPath: z.ZodOptional; - scriptLoading: z.ZodOptional>; + base: z.ZodOptional; + target: z.ZodOptional>; + }, "strict", z.ZodTypeAny, { + target?: "_self" | "_blank" | "_parent" | "_top" | undefined; + href?: string | undefined; + }, { + target?: "_self" | "_blank" | "_parent" | "_top" | undefined; + href?: string | undefined; + }>]>>; + scriptLoading: z.ZodOptional>; chunks: z.ZodOptional>; - excludedChunks: z.ZodOptional>; + excludeChunks: z.ZodOptional>; sri: z.ZodOptional>; minify: z.ZodOptional; title: z.ZodOptional; favicon: z.ZodOptional; meta: z.ZodOptional]>>>; + hash: z.ZodOptional; }, "strict", z.ZodTypeAny, { filename?: string | undefined; publicPath?: string | undefined; + hash?: boolean | undefined; chunks?: string[] | undefined; template?: string | undefined; templateContent?: string | undefined; templateParameters?: Record | undefined; inject?: boolean | "head" | "body" | undefined; - scriptLoading?: "module" | "blocking" | "defer" | undefined; - excludedChunks?: string[] | undefined; + base?: string | { + target?: "_self" | "_blank" | "_parent" | "_top" | undefined; + href?: string | undefined; + } | undefined; + scriptLoading?: "module" | "blocking" | "defer" | "systemjs-module" | undefined; + excludeChunks?: string[] | undefined; sri?: "sha256" | "sha384" | "sha512" | undefined; minify?: boolean | undefined; title?: string | undefined; @@ -4660,13 +4686,18 @@ const htmlRspackPluginOptions: z.ZodObject<{ }, { filename?: string | undefined; publicPath?: string | undefined; + hash?: boolean | undefined; chunks?: string[] | undefined; template?: string | undefined; templateContent?: string | undefined; templateParameters?: Record | undefined; inject?: boolean | "head" | "body" | undefined; - scriptLoading?: "module" | "blocking" | "defer" | undefined; - excludedChunks?: string[] | undefined; + base?: string | { + target?: "_self" | "_blank" | "_parent" | "_top" | undefined; + href?: string | undefined; + } | undefined; + scriptLoading?: "module" | "blocking" | "defer" | "systemjs-module" | undefined; + excludeChunks?: string[] | undefined; sri?: "sha256" | "sha384" | "sha512" | undefined; minify?: boolean | undefined; title?: string | undefined; diff --git a/packages/rspack/src/builtin-plugin/HtmlRspackPlugin.ts b/packages/rspack/src/builtin-plugin/HtmlRspackPlugin.ts index f0b478208fc0..c0d253ccb758 100644 --- a/packages/rspack/src/builtin-plugin/HtmlRspackPlugin.ts +++ b/packages/rspack/src/builtin-plugin/HtmlRspackPlugin.ts @@ -14,14 +14,26 @@ const htmlRspackPluginOptions = z.strictObject({ templateParameters: z.record(z.string()).optional(), inject: z.enum(["head", "body"]).or(z.boolean()).optional(), publicPath: z.string().optional(), - scriptLoading: z.enum(["blocking", "defer", "module"]).optional(), + base: z + .string() + .or( + z.strictObject({ + href: z.string().optional(), + target: z.enum(["_self", "_blank", "_parent", "_top"]).optional() + }) + ) + .optional(), + scriptLoading: z + .enum(["blocking", "defer", "module", "systemjs-module"]) + .optional(), chunks: z.string().array().optional(), - excludedChunks: z.string().array().optional(), + excludeChunks: z.string().array().optional(), sri: z.enum(["sha256", "sha384", "sha512"]).optional(), minify: z.boolean().optional(), title: z.string().optional(), favicon: z.string().optional(), - meta: z.record(z.string().or(z.record(z.string()))).optional() + meta: z.record(z.string().or(z.record(z.string()))).optional(), + hash: z.boolean().optional() }); export type HtmlRspackPluginOptions = z.infer; export const HtmlRspackPlugin = create( @@ -53,11 +65,13 @@ export const HtmlRspackPlugin = create( : configInject === false ? "false" : configInject; + const base = typeof c.base === "string" ? { href: c.base } : c.base; return { ...c, meta, scriptLoading, - inject + inject, + base }; } ); diff --git a/tests/plugin-test/html-plugin/basic.test.js b/tests/plugin-test/html-plugin/basic.test.js index df350d369a38..3c39ccc2f1a0 100644 --- a/tests/plugin-test/html-plugin/basic.test.js +++ b/tests/plugin-test/html-plugin/basic.test.js @@ -139,49 +139,47 @@ describe("HtmlWebpackPlugin", () => { ); }); - // TODO: url encodes the file name - // it("properly encodes file names in emitted URIs", (done) => { - // testHtmlPlugin( - // { - // mode: "production", - // entry: path.join(__dirname, "fixtures/index.js"), - // output: { - // path: OUTPUT_DIR, - // filename: "foo/very fancy+name.js", - // }, - // plugins: [new HtmlWebpackPlugin()], - // }, - // [ - // /', + '', ], null, done, @@ -3668,7 +3644,7 @@ describe("HtmlWebpackPlugin", () => { ], }, [ - '', + '', ], null, done, diff --git a/website/docs/en/plugins/rspack/html-rspack-plugin.mdx b/website/docs/en/plugins/rspack/html-rspack-plugin.mdx index 86a27602af24..75e03a607d94 100644 --- a/website/docs/en/plugins/rspack/html-rspack-plugin.mdx +++ b/website/docs/en/plugins/rspack/html-rspack-plugin.mdx @@ -74,7 +74,7 @@ type HtmlRspackPluginOptions = { publicPath?: string; scriptLoading?: 'blocking' | 'defer' | 'module'; chunks?: string[]; - excludedChunks?: string[]; + excludeChunks?: string[]; sri?: 'sha256' | 'sha384' | 'sha512'; minify?: boolean; favicon?: string; @@ -162,7 +162,7 @@ type HtmlRspackPluginOptions = { description: 'Allows you to add only some chunks.', }, { - name: '`excludedChunks`', + name: '`excludeChunks`', type: '`string[]|undefined`', default: 'undefined', description: 'Allows you to skip some chunks.', diff --git a/website/docs/zh/plugins/rspack/html-rspack-plugin.mdx b/website/docs/zh/plugins/rspack/html-rspack-plugin.mdx index 7e2f6d7586ce..1f09070bf15e 100644 --- a/website/docs/zh/plugins/rspack/html-rspack-plugin.mdx +++ b/website/docs/zh/plugins/rspack/html-rspack-plugin.mdx @@ -74,7 +74,7 @@ type HtmlRspackPluginOptions = { publicPath?: string; scriptLoading?: 'blocking' | 'defer' | 'module'; chunks?: string[]; - excludedChunks?: string[]; + excludeChunks?: string[]; sri?: 'sha256' | 'sha384' | 'sha512'; minify?: boolean; favicon?: string; @@ -160,7 +160,7 @@ type HtmlRspackPluginOptions = { description: '配置需要注入的 chunk,默认注入所有 chunk', }, { - name: '`excludedChunks`', + name: '`excludeChunks`', type: '`string[]|undefined`', default: 'undefined', description: '配置需要跳过注入的 chunk',