diff --git a/Cargo.lock b/Cargo.lock index 279351836d5..dca898dc2d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -507,6 +507,12 @@ dependencies = [ "windows-sys 0.33.0", ] +[[package]] +name = "cow-utils" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79" + [[package]] name = "cpufeatures" version = "0.2.9" @@ -2943,6 +2949,7 @@ name = "rspack_binding_options" version = "0.1.0" dependencies = [ "async-trait", + "cow-utils", "derivative", "glob", "napi-derive", @@ -3010,6 +3017,7 @@ dependencies = [ name = "rspack_binding_values" version = "0.1.0" dependencies = [ + "cow-utils", "futures", "heck 0.5.0", "napi-derive", @@ -3046,6 +3054,7 @@ dependencies = [ "async-recursion", "async-trait", "bitflags 2.5.0", + "cow-utils", "dashmap 5.5.3", "derivative", "dyn-clone", @@ -3105,6 +3114,7 @@ name = "rspack_error" version = "0.1.0" dependencies = [ "anyhow", + "cow-utils", "derivative", "futures", "miette 5.10.0", @@ -3325,6 +3335,7 @@ version = "0.1.0" dependencies = [ "async-trait", "color-backtrace", + "cow-utils", "napi-build", "napi-derive", "napi-h", @@ -3377,6 +3388,7 @@ name = "rspack_plugin_banner" version = "0.1.0" dependencies = [ "async-recursion", + "cow-utils", "futures", "regex", "rspack_core", @@ -3416,6 +3428,7 @@ name = "rspack_plugin_css" version = "0.1.0" dependencies = [ "async-trait", + "cow-utils", "css-module-lexer", "heck 0.5.0", "indexmap 1.9.3", @@ -3440,6 +3453,7 @@ name = "rspack_plugin_devtool" version = "0.1.0" dependencies = [ "async-trait", + "cow-utils", "dashmap 5.5.3", "derivative", "futures", @@ -3513,6 +3527,7 @@ name = "rspack_plugin_extract_css" version = "0.1.0" dependencies = [ "async-trait", + "cow-utils", "regex", "rspack_collections", "rspack_core", @@ -3535,6 +3550,7 @@ name = "rspack_plugin_hmr" version = "0.1.0" dependencies = [ "async-trait", + "cow-utils", "rspack_collections", "rspack_core", "rspack_error", @@ -3550,6 +3566,7 @@ name = "rspack_plugin_html" version = "0.1.0" dependencies = [ "anyhow", + "cow-utils", "dashmap 5.5.3", "futures", "itertools 0.13.0", @@ -3594,6 +3611,7 @@ dependencies = [ "anymap", "async-trait", "bitflags 2.5.0", + "cow-utils", "dashmap 5.5.3", "fast-glob", "indexmap 2.2.6", @@ -3629,6 +3647,7 @@ dependencies = [ name = "rspack_plugin_json" version = "0.1.0" dependencies = [ + "cow-utils", "json", "ropey", "rspack_core", @@ -3641,6 +3660,7 @@ name = "rspack_plugin_lazy_compilation" version = "0.1.0" dependencies = [ "async-trait", + "cow-utils", "rspack_collections", "rspack_core", "rspack_error", @@ -3788,6 +3808,7 @@ name = "rspack_plugin_runtime" version = "0.1.0" dependencies = [ "async-trait", + "cow-utils", "indexmap 2.2.6", "itertools 0.13.0", "rspack_collections", @@ -3865,6 +3886,7 @@ dependencies = [ name = "rspack_plugin_swc_js_minimizer" version = "0.1.0" dependencies = [ + "cow-utils", "once_cell", "rayon", "regex", @@ -3885,6 +3907,7 @@ dependencies = [ name = "rspack_plugin_warn_sensitive_module" version = "0.1.0" dependencies = [ + "cow-utils", "rspack_collections", "rspack_core", "rspack_error", @@ -3898,6 +3921,7 @@ name = "rspack_plugin_wasm" version = "0.1.0" dependencies = [ "async-trait", + "cow-utils", "dashmap 5.5.3", "indexmap 2.2.6", "rayon", @@ -3934,6 +3958,7 @@ dependencies = [ name = "rspack_regex" version = "0.1.0" dependencies = [ + "cow-utils", "regex-syntax 0.8.3", "regress", "rspack_error", @@ -5606,6 +5631,7 @@ dependencies = [ name = "swc_plugin_import" version = "0.1.5" dependencies = [ + "cow-utils", "handlebars", "heck 0.5.0", "rustc-hash 1.1.0", diff --git a/Cargo.toml b/Cargo.toml index 43ffb7f1fc9..25876a972bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ async-trait = { version = "0.1.79" } bitflags = { version = "2.5.0" } camino = { version = "1.1.8" } concat-string = { version = "1.0.1" } +cow-utils = { version = "0.1.3" } css-module-lexer = { version = "0.0.14" } dashmap = { version = "5.5.3" } derivative = { version = "2.2.0" } diff --git a/clippy.toml b/clippy.toml index 83abd4f8199..9f60810ef5e 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,2 +1,11 @@ allow-dbg-in-tests = true allow-unwrap-in-tests = true + +disallowed-methods = [ + { path = "str::to_ascii_lowercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_ascii_lowercase` instead." }, + { path = "str::to_ascii_uppercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_ascii_uppercase` instead." }, + { path = "str::to_lowercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_lowercase` instead." }, + { path = "str::to_uppercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_uppercase` instead." }, + { path = "str::replace", reason = "To avoid memory allocation, use `cow_utils::CowUtils::replace` instead." }, + { path = "str::replacen", reason = "To avoid memory allocation, use `cow_utils::CowUtils::replacen` instead." }, +] \ No newline at end of file diff --git a/crates/node_binding/Cargo.toml b/crates/node_binding/Cargo.toml index 074104cf18e..d4af5e01823 100644 --- a/crates/node_binding/Cargo.toml +++ b/crates/node_binding/Cargo.toml @@ -32,6 +32,7 @@ rspack_tracing = { version = "0.1.0", path = "../rspack_tracing" } tokio = { workspace = true, features = ["rt", "rt-multi-thread"] } async-trait = { workspace = true } +cow-utils = { workspace = true } once_cell = { workspace = true } tracing = { workspace = true } diff --git a/crates/node_binding/src/plugins/interceptor.rs b/crates/node_binding/src/plugins/interceptor.rs index 5b84aef9d6d..1d84c44b495 100644 --- a/crates/node_binding/src/plugins/interceptor.rs +++ b/crates/node_binding/src/plugins/interceptor.rs @@ -5,6 +5,7 @@ use std::{ }; use async_trait::async_trait; +use cow_utils::CowUtils; use napi::{ bindgen_prelude::{Buffer, FromNapiValue, Promise, ToNapiValue}, Env, JsFunction, NapiRaw, @@ -1161,7 +1162,11 @@ impl CompilationRuntimeModule for CompilationRuntimeModuleTap { ), module_identifier: module.identifier().to_string(), constructor_name: module.get_constructor_name(), - name: module.name().to_string().replace("webpack/runtime/", ""), + name: module + .name() + .as_str() + .cow_replace("webpack/runtime/", "") + .into_owned(), }, chunk: JsChunk::from(chunk), }; diff --git a/crates/rspack_binding_options/Cargo.toml b/crates/rspack_binding_options/Cargo.toml index c84ccb06143..46fbe4e23e8 100644 --- a/crates/rspack_binding_options/Cargo.toml +++ b/crates/rspack_binding_options/Cargo.toml @@ -14,6 +14,7 @@ ignored = ["tracing"] [dependencies] async-trait = { workspace = true } +cow-utils = { workspace = true } derivative = { workspace = true } glob = { workspace = true } napi = { workspace = true, features = ["async", "tokio_rt", "serde-json", "anyhow"] } diff --git a/crates/rspack_binding_options/src/options/raw_builtins/raw_copy.rs b/crates/rspack_binding_options/src/options/raw_builtins/raw_copy.rs index ecf999ed571..ea128b54bae 100644 --- a/crates/rspack_binding_options/src/options/raw_builtins/raw_copy.rs +++ b/crates/rspack_binding_options/src/options/raw_builtins/raw_copy.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use derivative::Derivative; use napi::{bindgen_prelude::Buffer, Either}; use napi_derive::napi; @@ -110,7 +111,7 @@ impl From for CopyPattern { }), context: context.map(Into::into), to_type: if let Some(to_type) = to_type { - match to_type.to_lowercase().as_str() { + match to_type.cow_to_lowercase().as_ref() { "dir" => Some(ToType::Dir), "file" => Some(ToType::File), "template" => Some(ToType::Template), diff --git a/crates/rspack_binding_values/Cargo.toml b/crates/rspack_binding_values/Cargo.toml index 25b2dc04f93..10a2272b252 100644 --- a/crates/rspack_binding_values/Cargo.toml +++ b/crates/rspack_binding_values/Cargo.toml @@ -6,6 +6,7 @@ name = "rspack_binding_values" repository = "https://github.com/web-infra-dev/rspack" version = "0.1.0" [dependencies] +cow-utils = { workspace = true } futures = { workspace = true } heck = { workspace = true } napi = { workspace = true, features = ["async", "tokio_rt", "serde-json", "anyhow"] } diff --git a/crates/rspack_binding_values/src/html.rs b/crates/rspack_binding_values/src/html.rs index 17ffdce617a..0743a0d69a1 100644 --- a/crates/rspack_binding_values/src/html.rs +++ b/crates/rspack_binding_values/src/html.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use cow_utils::CowUtils; use napi::Either; use napi_derive::napi; use rspack_plugin_html::{ @@ -54,13 +55,13 @@ impl From for HtmlPluginTag { .filter_map(|(key, value)| { value.as_ref().and_then(|v| match v { Either::A(x) => Some(HtmlPluginAttribute { - attr_name: key.to_ascii_lowercase(), - attr_value: Some(x.to_ascii_lowercase()), + attr_name: key.cow_to_ascii_lowercase().into_owned(), + attr_value: Some(x.cow_to_ascii_lowercase().into_owned()), }), Either::B(x) => { if *x { Some(HtmlPluginAttribute { - attr_name: key.to_ascii_lowercase(), + attr_name: key.cow_to_ascii_lowercase().into_owned(), attr_value: None, }) } else { diff --git a/crates/rspack_binding_values/src/runtime.rs b/crates/rspack_binding_values/src/runtime.rs index b8768032a96..a1289d05af3 100644 --- a/crates/rspack_binding_values/src/runtime.rs +++ b/crates/rspack_binding_values/src/runtime.rs @@ -1,5 +1,6 @@ use std::sync::LazyLock; +use cow_utils::CowUtils; use heck::{ToLowerCamelCase, ToSnakeCase}; use napi_derive::napi; use rspack_core::RuntimeGlobals; @@ -129,9 +130,10 @@ impl JsAdditionalTreeRuntimeRequirementsResult { let mut runtime_requirements = RuntimeGlobals::default(); for item in self.runtime_requirements.value.iter() { - let name = item.to_snake_case().to_uppercase(); + let snake_case = item.to_snake_case(); + let name = snake_case.cow_to_uppercase(); - if let Some(item) = RUNTIME_GLOBAL_MAP.1.get(&name) { + if let Some(item) = RUNTIME_GLOBAL_MAP.1.get(name.as_ref()) { runtime_requirements.extend(*item); } } diff --git a/crates/rspack_core/Cargo.toml b/crates/rspack_core/Cargo.toml index ed85d0ed8da..5cd76ab5d8d 100644 --- a/crates/rspack_core/Cargo.toml +++ b/crates/rspack_core/Cargo.toml @@ -10,6 +10,7 @@ anymap = { workspace = true } async-recursion = { workspace = true } async-trait = { workspace = true } bitflags = { workspace = true } +cow-utils = { workspace = true } dashmap = { workspace = true, features = ["rayon"] } derivative = { workspace = true } dyn-clone = "1.0.17" diff --git a/crates/rspack_core/src/context_module.rs b/crates/rspack_core/src/context_module.rs index 3c03318d9d3..5a3de3df9fc 100644 --- a/crates/rspack_core/src/context_module.rs +++ b/crates/rspack_core/src/context_module.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use std::sync::LazyLock; use std::{borrow::Cow, fs, hash::Hash, sync::Arc}; +use cow_utils::CowUtils; use indoc::formatdoc; use itertools::Itertools; use regex::{Captures, Regex}; @@ -1026,12 +1027,9 @@ impl ContextModule { // FIXME: nodejs resolver return path of context, sometimes is '/a/b', sometimes is '/a/b/' let relative_path = { - let mut path_str = path_str.to_owned(); - let p = path_str - .drain(ctx.len()..) - .collect::() - .replace('\\', "/"); - if p.starts_with('/') { + let path_str = path_str.to_owned().drain(ctx.len()..).collect::(); + let p = path_str.cow_replace('\\', "/"); + if p.as_ref().starts_with('/') { format!(".{p}") } else { format!("./{p}") @@ -1301,9 +1299,13 @@ fn alternative_requests( items.push(item.clone()); // TODO resolveOptions.modules can be array for module in resolve_options.modules() { - let dir = module.replace('\\', "/"); - let full_path: String = format!("{}{}", item.context.replace('\\', "/"), &item.request[1..]); - if full_path.starts_with(&dir) { + let dir = module.cow_replace('\\', "/"); + let full_path: String = format!( + "{}{}", + item.context.cow_replace('\\', "/"), + &item.request[1..] + ); + if full_path.starts_with(dir.as_ref()) { items.push(AlternativeRequest::new( item.context.clone(), full_path[(dir.len() + 1)..].to_string(), diff --git a/crates/rspack_core/src/context_module_factory.rs b/crates/rspack_core/src/context_module_factory.rs index 128704ed912..e987effcdb5 100644 --- a/crates/rspack_core/src/context_module_factory.rs +++ b/crates/rspack_core/src/context_module_factory.rs @@ -1,5 +1,6 @@ -use std::sync::Arc; +use std::{borrow::Cow, sync::Arc}; +use cow_utils::CowUtils; use rspack_error::{error, Result}; use rspack_hook::define_hook; use rspack_paths::Utf8PathBuf; @@ -164,15 +165,16 @@ impl ContextModuleFactory { let (loader_request, specifier) = match request.rfind('!') { Some(idx) => { let mut loaders_prefix = String::new(); - let mut loaders_request = request[..idx + 1].to_string(); let mut i = 0; + + let loaders_request = Cow::Borrowed(&request[..idx + 1]); while i < loaders_request.len() && loaders_request.chars().nth(i) == Some('!') { loaders_prefix.push('!'); i += 1; } - loaders_request = loaders_request[i..] + let loaders_request = loaders_request.as_ref()[i..] .trim_end_matches('!') - .replace("!!", "!"); + .cow_replace("!!", "!"); let loaders = if loaders_request.is_empty() { vec![] diff --git a/crates/rspack_core/src/utils/template.rs b/crates/rspack_core/src/utils/template.rs index a27ad53ac41..11dab996a69 100644 --- a/crates/rspack_core/src/utils/template.rs +++ b/crates/rspack_core/src/utils/template.rs @@ -1,6 +1,8 @@ +use cow_utils::CowUtils; + pub fn to_normal_comment(str: &str) -> String { if str.is_empty() { return String::new(); } - format!("/* {} */", str.replace("*/", "* /")) + format!("/* {} */", str.cow_replace("*/", "* /")) } diff --git a/crates/rspack_error/Cargo.toml b/crates/rspack_error/Cargo.toml index 362a2a691ae..71e8f81715f 100644 --- a/crates/rspack_error/Cargo.toml +++ b/crates/rspack_error/Cargo.toml @@ -9,6 +9,7 @@ version = "0.1.0" [dependencies] anyhow = { workspace = true, features = ["backtrace"] } +cow-utils = { workspace = true } derivative = { workspace = true } futures = { workspace = true } miette = { version = "5", features = ["fancy"] } diff --git a/crates/rspack_error/src/diagnostic.rs b/crates/rspack_error/src/diagnostic.rs index ede6650ce96..75b9bf3818d 100644 --- a/crates/rspack_error/src/diagnostic.rs +++ b/crates/rspack_error/src/diagnostic.rs @@ -1,5 +1,6 @@ use std::{fmt, ops::Deref, sync::Arc}; +use cow_utils::CowUtils; use miette::{GraphicalTheme, IntoDiagnostic, MietteDiagnostic}; use rspack_collections::Identifier; use rspack_paths::{Utf8Path, Utf8PathBuf}; @@ -37,8 +38,8 @@ impl From for RspackSeverity { impl From<&str> for RspackSeverity { fn from(value: &str) -> Self { - let s = value.to_ascii_lowercase(); - match s.as_str() { + let s = value.cow_to_ascii_lowercase(); + match s.as_ref() { "warning" => RspackSeverity::Warn, _ => RspackSeverity::Error, } diff --git a/crates/rspack_plugin_banner/Cargo.toml b/crates/rspack_plugin_banner/Cargo.toml index a299a9f05ff..8b878751d58 100644 --- a/crates/rspack_plugin_banner/Cargo.toml +++ b/crates/rspack_plugin_banner/Cargo.toml @@ -9,6 +9,7 @@ version = "0.1.0" [dependencies] async-recursion = { workspace = true } +cow-utils = { workspace = true } futures = { workspace = true } regex = { workspace = true } rspack_core = { version = "0.1.0", path = "../rspack_core" } diff --git a/crates/rspack_plugin_banner/src/lib.rs b/crates/rspack_plugin_banner/src/lib.rs index 90803bf298a..b4d5f86cd31 100644 --- a/crates/rspack_plugin_banner/src/lib.rs +++ b/crates/rspack_plugin_banner/src/lib.rs @@ -4,6 +4,7 @@ use std::fmt::{self, Debug}; use std::sync::LazyLock; use async_recursion::async_recursion; +use cow_utils::CowUtils; use futures::future::BoxFuture; use regex::Regex; use rspack_core::{ @@ -125,7 +126,7 @@ fn wrap_comment(str: &str) -> String { } let result = str - .replace("*/", "* /") + .cow_replace("*/", "* /") .split('\n') .collect::>() .join("\n * "); diff --git a/crates/rspack_plugin_css/Cargo.toml b/crates/rspack_plugin_css/Cargo.toml index dfe67cca8b9..74f69b0f301 100644 --- a/crates/rspack_plugin_css/Cargo.toml +++ b/crates/rspack_plugin_css/Cargo.toml @@ -7,6 +7,7 @@ repository = "https://github.com/web-infra-dev/rspack" version = "0.1.0" [dependencies] async-trait = { workspace = true } +cow-utils = { workspace = true } css-module-lexer = { workspace = true } heck = { workspace = true } indexmap = { version = "=1.9.3", features = ["serde-1"] } diff --git a/crates/rspack_plugin_css/src/runtime/mod.rs b/crates/rspack_plugin_css/src/runtime/mod.rs index aa6b7b2dc38..523f9510b39 100644 --- a/crates/rspack_plugin_css/src/runtime/mod.rs +++ b/crates/rspack_plugin_css/src/runtime/mod.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ basic_function, compile_boolean_matcher, impl_runtime_module, @@ -198,14 +199,15 @@ for(i = 0; cc; i++) {{ source.add(RawSource::from( include_str!("./css_loading.js") - .replace( + .cow_replace( "__CROSS_ORIGIN_LOADING_PLACEHOLDER__", &cross_origin_content, ) - .replace("__CSS_CHUNK_DATA__", &load_css_chunk_data) - .replace("__CHUNK_LOAD_TIMEOUT_PLACEHOLDER__", &chunk_load_timeout) - .replace("__UNIQUE_NAME__", unique_name) - .replace("__INITIAL_CSS_CHUNK_DATA__", &load_initial_chunk_data), + .cow_replace("__CSS_CHUNK_DATA__", &load_css_chunk_data) + .cow_replace("__CHUNK_LOAD_TIMEOUT_PLACEHOLDER__", &chunk_load_timeout) + .cow_replace("__UNIQUE_NAME__", unique_name) + .cow_replace("__INITIAL_CSS_CHUNK_DATA__", &load_initial_chunk_data) + .into_owned(), )); if with_loading { @@ -216,16 +218,17 @@ for(i = 0; cc; i++) {{ ); source.add(RawSource::from( include_str!("./css_loading_with_loading.js") - .replace("$CHUNK_LOADING_GLOBAL_EXPR$", &chunk_loading_global_expr) - .replace("CSS_MATCHER", &has_css_matcher.render("chunkId")) - .replace( + .cow_replace("$CHUNK_LOADING_GLOBAL_EXPR$", &chunk_loading_global_expr) + .cow_replace("CSS_MATCHER", &has_css_matcher.render("chunkId")) + .cow_replace( "$FETCH_PRIORITY$", if with_fetch_priority { ", fetchPriority" } else { "" }, - ), + ) + .into_owned(), )); } diff --git a/crates/rspack_plugin_css/src/utils.rs b/crates/rspack_plugin_css/src/utils.rs index eda2c78c2f1..da5bfe22130 100644 --- a/crates/rspack_plugin_css/src/utils.rs +++ b/crates/rspack_plugin_css/src/utils.rs @@ -4,6 +4,7 @@ use std::hash::Hasher; use std::sync::Arc; use std::sync::LazyLock; +use cow_utils::CowUtils; use heck::{ToKebabCase, ToLowerCamelCase}; use indexmap::{IndexMap, IndexSet}; use regex::{Captures, Regex}; @@ -101,13 +102,15 @@ struct LocalIdentNameRenderOptions<'a> { impl LocalIdentNameRenderOptions<'_> { pub fn render_local_ident_name(self, local_ident_name: &LocalIdentName) -> String { - let mut s = local_ident_name + let raw = local_ident_name .template .render(self.path_data, None) .always_ok(); - s = s.replace("[uniqueName]", self.unique_name); - s = s.replace("[local]", self.local); - s + let s: &str = raw.as_ref(); + + s.cow_replace("[uniqueName]", self.unique_name) + .cow_replace("[local]", self.local) + .into_owned() } } diff --git a/crates/rspack_plugin_devtool/Cargo.toml b/crates/rspack_plugin_devtool/Cargo.toml index e800887f1d4..757c1b1582a 100644 --- a/crates/rspack_plugin_devtool/Cargo.toml +++ b/crates/rspack_plugin_devtool/Cargo.toml @@ -9,6 +9,7 @@ version = "0.1.0" [dependencies] async-trait = { workspace = true } +cow-utils = { workspace = true } dashmap = { workspace = true } derivative = { workspace = true } futures = { workspace = true } diff --git a/crates/rspack_plugin_devtool/src/eval_dev_tool_module_plugin.rs b/crates/rspack_plugin_devtool/src/eval_dev_tool_module_plugin.rs index 1f2877ba710..6feb55ea707 100644 --- a/crates/rspack_plugin_devtool/src/eval_dev_tool_module_plugin.rs +++ b/crates/rspack_plugin_devtool/src/eval_dev_tool_module_plugin.rs @@ -1,6 +1,7 @@ use std::sync::LazyLock; use std::{borrow::Cow, hash::Hash}; +use cow_utils::CowUtils; use dashmap::DashMap; use derivative::Derivative; use rspack_collections::UkeySet; @@ -127,13 +128,13 @@ fn eval_devtool_plugin_render_module_content( let source = &origin_source.source(); let footer = format!( "\n{}", - self.source_url_comment.replace( + &self.source_url_comment.cow_replace( "[url]", encode_uri(&str) - .replace("%2F", "/") - .replace("%20", "_") - .replace("%5E", "^") - .replace("%5C", "\\") + .cow_replace("%2F", "/") + .cow_replace("%20", "_") + .cow_replace("%5E", "^") + .cow_replace("%5C", "\\") .trim_start_matches('/') ) ); diff --git a/crates/rspack_plugin_devtool/src/module_filename_helpers.rs b/crates/rspack_plugin_devtool/src/module_filename_helpers.rs index b966706b65c..a6357f22dbf 100644 --- a/crates/rspack_plugin_devtool/src/module_filename_helpers.rs +++ b/crates/rspack_plugin_devtool/src/module_filename_helpers.rs @@ -4,6 +4,7 @@ use std::{ hash::{Hash, Hasher}, }; +use cow_utils::CowUtils; use regex::{Captures, Regex}; use rspack_core::{contextify, Compilation, OutputOptions}; use rspack_error::Result; @@ -198,7 +199,7 @@ impl ModuleFilenameHelpers { .as_str(); if content.len() + 2 == full_match.len() { - match content.to_lowercase().as_str() { + match content.cow_to_lowercase().as_ref() { "identifier" => Cow::from(&ctx.identifier), "short-identifier" => Cow::from(&ctx.short_identifier), "resource" => Cow::from(&ctx.resource), diff --git a/crates/rspack_plugin_devtool/src/source_map_dev_tool_plugin.rs b/crates/rspack_plugin_devtool/src/source_map_dev_tool_plugin.rs index 37c902fc9ba..40808177134 100644 --- a/crates/rspack_plugin_devtool/src/source_map_dev_tool_plugin.rs +++ b/crates/rspack_plugin_devtool/src/source_map_dev_tool_plugin.rs @@ -1,6 +1,7 @@ use std::sync::LazyLock; use std::{borrow::Cow, path::Path}; +use cow_utils::CowUtils; use derivative::Derivative; use futures::future::{join_all, BoxFuture}; use itertools::Itertools; @@ -430,7 +431,9 @@ impl SourceMapDevToolPlugin { ConcatSource::new([ source.clone(), RawSource::from( - current_source_mapping_url_comment.replace("[url]", &source_map_url), + current_source_mapping_url_comment + .cow_replace("[url]", &source_map_url) + .into_owned(), ) .boxed(), ]) @@ -468,10 +471,14 @@ impl SourceMapDevToolPlugin { asset.source = Some( ConcatSource::new([ source.clone(), - RawSource::from(current_source_mapping_url_comment.replace( - "[url]", - &format!("data:application/json;charset=utf-8;base64,{base64}"), - )) + RawSource::from( + current_source_mapping_url_comment + .cow_replace( + "[url]", + &format!("data:application/json;charset=utf-8;base64,{base64}"), + ) + .into_owned(), + ) .boxed(), ]) .boxed(), diff --git a/crates/rspack_plugin_extract_css/Cargo.toml b/crates/rspack_plugin_extract_css/Cargo.toml index 1cb712930e6..78292cb343d 100644 --- a/crates/rspack_plugin_extract_css/Cargo.toml +++ b/crates/rspack_plugin_extract_css/Cargo.toml @@ -7,6 +7,7 @@ repository = "https://github.com/web-infra-dev/rspack" version = "0.1.0" [dependencies] async-trait = { workspace = true } +cow-utils = { workspace = true } regex = { workspace = true } rspack_collections = { version = "0.1.0", path = "../rspack_collections" } rspack_core = { version = "0.1.0", path = "../rspack_core" } diff --git a/crates/rspack_plugin_extract_css/src/plugin.rs b/crates/rspack_plugin_extract_css/src/plugin.rs index dc48d902ab1..64ed09f0dfd 100644 --- a/crates/rspack_plugin_extract_css/src/plugin.rs +++ b/crates/rspack_plugin_extract_css/src/plugin.rs @@ -1,6 +1,7 @@ use std::sync::LazyLock; use std::{borrow::Cow, cmp::max, hash::Hash, sync::Arc}; +use cow_utils::CowUtils; use regex::Regex; use rspack_collections::{IdentifierMap, IdentifierSet, UkeySet}; use rspack_core::ChunkGraph; @@ -334,7 +335,7 @@ impl PluginCssExtract { let starts_with_at_import = STARTS_WITH_AT_IMPORT_REGEX.is_match(&content); let header = self.options.pathinfo.then(|| { - let req_str = readable_identifier.replace("*/", "*_/"); + let req_str = readable_identifier.cow_replace("*/", "*_/"); let req_str_star = "*".repeat(req_str.len()); RawSource::from(format!( "/*!****{req_str_star}****!*\\\n !*** {req_str} ***!\n \\****{req_str_star}****/\n" diff --git a/crates/rspack_plugin_extract_css/src/runtime.rs b/crates/rspack_plugin_extract_css/src/runtime.rs index d5a80173d17..d41e7f30fb7 100644 --- a/crates/rspack_plugin_extract_css/src/runtime.rs +++ b/crates/rspack_plugin_extract_css/src/runtime.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use cow_utils::CowUtils; use rspack_collections::UkeySet; use rspack_core::{ impl_runtime_module, rspack_sources::RawSource, ChunkUkey, Compilation, CrossOriginLoading, @@ -80,18 +81,18 @@ impl RuntimeModule for CssLoadingRuntimeModule { for (attr_key, attr_value) in attributes { attr += &format!("linkTag.setAttribute({}, {});\n", attr_key, attr_value); } - let runtime = runtime.replace("__SET_ATTRIBUTES__", &attr); + let runtime = runtime.cow_replace("__SET_ATTRIBUTES__", &attr); let runtime = if let Some(link_type) = &self.link_type { - runtime.replace("__SET_LINKTYPE__", &format!("linkTag.type={};", link_type)) + runtime.cow_replace("__SET_LINKTYPE__", &format!("linkTag.type={};", link_type)) } else { - runtime.replace("__SET_LINKTYPE__", "") + runtime.cow_replace("__SET_LINKTYPE__", "") }; let runtime = if let CrossOriginLoading::Enable(cross_origin_loading) = &compilation.options.output.cross_origin_loading { - runtime.replace( + runtime.cow_replace( "__CROSS_ORIGIN_LOADING__", &format!( "if (linkTag.href.indexOf(window.location.origin + '/') !== 0) {{ @@ -101,16 +102,16 @@ impl RuntimeModule for CssLoadingRuntimeModule { ), ) } else { - runtime.replace("__CROSS_ORIGIN_LOADING__", "") + runtime.cow_replace("__CROSS_ORIGIN_LOADING__", "") }; let runtime = match &self.insert { - InsertType::Fn(f) => runtime.replace("__INSERT__", &format!("({f})(linkTag);")), - InsertType::Selector(sel) => runtime.replace( + InsertType::Fn(f) => runtime.cow_replace("__INSERT__", &format!("({f})(linkTag);")), + InsertType::Selector(sel) => runtime.cow_replace( "__INSERT__", &format!("var target = document.querySelector({sel});\ntarget.parentNode.insertBefore(linkTag, target.nextSibling);"), ), - InsertType::Default => runtime.replace( + InsertType::Default => runtime.cow_replace( "__INSERT__", "if (oldTag) { oldTag.parentNode.insertBefore(linkTag, oldTag.nextSibling); @@ -123,10 +124,10 @@ impl RuntimeModule for CssLoadingRuntimeModule { let runtime = if self.loading { let chunks = self.get_css_chunks(compilation); if chunks.is_empty() { - runtime.replace("__WITH_LOADING__", "// no chunk loading") + runtime.cow_replace("__WITH_LOADING__", "// no chunk loading") } else { let chunk = compilation.chunk_by_ukey.expect_get(&self.chunk); - let with_loading = WITH_LOADING.replace( + let with_loading = WITH_LOADING.cow_replace( "__INSTALLED_CHUNKS__", &chunk .ids @@ -139,12 +140,12 @@ impl RuntimeModule for CssLoadingRuntimeModule { }), ); - let with_loading = with_loading.replace( + let with_loading = with_loading.cow_replace( "__ENSURE_CHUNK_HANDLERS__", &RuntimeGlobals::ENSURE_CHUNK_HANDLERS.to_string(), ); - let with_loading = with_loading.replace( + let with_loading = with_loading.cow_replace( "__CSS_CHUNKS__", &format!( "{{\n{}\n}}", @@ -164,24 +165,24 @@ impl RuntimeModule for CssLoadingRuntimeModule { ), ); - runtime.replace("__WITH_LOADING__", &with_loading) + runtime.cow_replace("__WITH_LOADING__", &with_loading) } } else { - runtime.replace("__WITH_LOADING__", "// no chunk loading") + runtime.cow_replace("__WITH_LOADING__", "// no chunk loading") }; let runtime = if self.hmr { - runtime.replace( + runtime.cow_replace( "__WITH_HMT__", - &WITH_HMR.replace( + &WITH_HMR.cow_replace( "__HMR_DOWNLOAD__", &RuntimeGlobals::HMR_DOWNLOAD_UPDATE_HANDLERS.to_string(), ), ) } else { - runtime.replace("__WITH_HMT__", "// no hmr") + runtime.cow_replace("__WITH_HMT__", "// no hmr") }; - Ok(Arc::new(RawSource::from(runtime))) + Ok(Arc::new(RawSource::from(runtime.into_owned()))) } } diff --git a/crates/rspack_plugin_hmr/Cargo.toml b/crates/rspack_plugin_hmr/Cargo.toml index c8de0cec6e6..861896c45fb 100644 --- a/crates/rspack_plugin_hmr/Cargo.toml +++ b/crates/rspack_plugin_hmr/Cargo.toml @@ -14,6 +14,7 @@ rspack_hook = { version = "0.1.0", path = "../rspack_hook" } rspack_util = { version = "0.1.0", path = "../rspack_util" } async-trait = { workspace = true } +cow-utils = { workspace = true } rustc-hash = { workspace = true } serde_json = { workspace = true } tracing = { workspace = true } diff --git a/crates/rspack_plugin_hmr/src/hot_module_replacement.rs b/crates/rspack_plugin_hmr/src/hot_module_replacement.rs index 0cdd36d5995..15d236d4fdd 100644 --- a/crates/rspack_plugin_hmr/src/hot_module_replacement.rs +++ b/crates/rspack_plugin_hmr/src/hot_module_replacement.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ impl_runtime_module, @@ -27,8 +28,9 @@ impl RuntimeModule for HotModuleReplacementRuntimeModule { Ok( RawSource::from( include_str!("runtime/hot_module_replacement.js") - .replace("$HOT_TEST_GLOBAL$", &HOT_TEST_DEFINE_GLOBAL) - .replace("$HOT_TEST_STATUS$", &HOT_TEST_STATUS_CHANGE), + .cow_replace("$HOT_TEST_GLOBAL$", &HOT_TEST_DEFINE_GLOBAL) + .cow_replace("$HOT_TEST_STATUS$", &HOT_TEST_STATUS_CHANGE) + .into_owned(), ) .boxed(), ) diff --git a/crates/rspack_plugin_html/Cargo.toml b/crates/rspack_plugin_html/Cargo.toml index ff564fea1dd..33db16f86e3 100644 --- a/crates/rspack_plugin_html/Cargo.toml +++ b/crates/rspack_plugin_html/Cargo.toml @@ -10,6 +10,7 @@ default = [] [dependencies] anyhow = { workspace = true } +cow-utils = { workspace = true } dashmap = { workspace = true } futures = { workspace = true } itertools = { workspace = true } diff --git a/crates/rspack_plugin_html/src/asset.rs b/crates/rspack_plugin_html/src/asset.rs index 467b7930ac0..56b254cdd49 100644 --- a/crates/rspack_plugin_html/src/asset.rs +++ b/crates/rspack_plugin_html/src/asset.rs @@ -7,6 +7,7 @@ use std::{ }; use anyhow::Context; +use cow_utils::CowUtils; use itertools::Itertools; use rayon::prelude::*; use regex::Regex; @@ -306,7 +307,7 @@ fn url_encode_path(file_path: &str) -> String { .map(|p| { urlencoding::encode(p) }) .join("/"), // element.outerHTML will escape '&' so need to add a placeholder here - query_string.replace("&", "$$RSPACK_URL_AMP$$") + query_string.cow_replace("&", "$$RSPACK_URL_AMP$$") ) } diff --git a/crates/rspack_plugin_html/src/plugin.rs b/crates/rspack_plugin_html/src/plugin.rs index 5a41c9ce783..a0190afbb53 100644 --- a/crates/rspack_plugin_html/src/plugin.rs +++ b/crates/rspack_plugin_html/src/plugin.rs @@ -1,5 +1,6 @@ use std::{path::PathBuf, sync::LazyLock}; +use cow_utils::CowUtils; use rspack_core::{ Compilation, CompilationId, CompilationProcessAssets, Filename, FilenameTemplate, NoFilenameFn, Plugin, @@ -155,17 +156,18 @@ async fn generate_html( current_ast.visit_mut_with(&mut visitor); } - let mut html = parser - .codegen(&mut current_ast, compilation)? - .replace("$$RSPACK_URL_AMP$$", "&"); + let raw_html = parser.codegen(&mut current_ast, compilation)?; + let html = raw_html.cow_replace("$$RSPACK_URL_AMP$$", "&"); - if !has_doctype { - html = html.replace("", ""); - } + let html = if has_doctype { + html + } else { + html.cow_replace("", "") + }; Ok(( template_file_name.to_string(), - html, + html.into_owned(), template.file_dependencies, )) } @@ -178,8 +180,8 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { let output_file_name = FilenameTemplate::from( config .filename - .replace("[templatehash]", "[contenthash]") - .clone(), + .cow_replace("[templatehash]", "[contenthash]") + .into_owned(), ); let (template_file_name, html) = diff --git a/crates/rspack_plugin_javascript/Cargo.toml b/crates/rspack_plugin_javascript/Cargo.toml index e1f7743fcde..d13ee8b9f15 100644 --- a/crates/rspack_plugin_javascript/Cargo.toml +++ b/crates/rspack_plugin_javascript/Cargo.toml @@ -9,6 +9,7 @@ version = "0.1.0" anymap = { workspace = true } async-trait = { workspace = true } bitflags = { workspace = true } +cow-utils = { workspace = true } dashmap = { workspace = true } fast-glob = "0.4.0" indexmap = { workspace = true } diff --git a/crates/rspack_plugin_javascript/src/parser_plugin/initialize_evaluating.rs b/crates/rspack_plugin_javascript/src/parser_plugin/initialize_evaluating.rs index e07d974f592..3577125edc8 100644 --- a/crates/rspack_plugin_javascript/src/parser_plugin/initialize_evaluating.rs +++ b/crates/rspack_plugin_javascript/src/parser_plugin/initialize_evaluating.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_core::SpanExt; use super::JavascriptParserPlugin; @@ -81,21 +82,17 @@ impl JavascriptParserPlugin for InitializeEvaluating { let s = if arg1.is_string() { param .string() - .replacen(arg1.string(), arg2.string().as_str(), 1) + .cow_replacen(arg1.string(), arg2.string().as_str(), 1) } else if arg1.regexp().1.contains('g') { let raw = arg1.regexp(); let regexp = eval_regexp_to_regexp(&raw.0, &raw.1); - regexp - .replace_all(param.string().as_ref(), arg2.string()) - .to_string() + regexp.replace_all(param.string().as_ref(), arg2.string()) } else { let raw = arg1.regexp(); let regexp = eval_regexp_to_regexp(&raw.0, &raw.1); - regexp - .replace(param.string().as_ref(), arg2.string()) - .to_string() + regexp.replace(param.string().as_ref(), arg2.string()) }; - res.set_string(s); + res.set_string(s.to_string()); res.set_side_effects(param.could_have_side_effects()); return Some(res); } else if property == CONCAT_METHOD_NAME && (param.is_string() || param.is_wrapped()) { diff --git a/crates/rspack_plugin_javascript/src/parser_plugin/provide_plugin.rs b/crates/rspack_plugin_javascript/src/parser_plugin/provide_plugin.rs index 3110da02358..1a59b6b9046 100644 --- a/crates/rspack_plugin_javascript/src/parser_plugin/provide_plugin.rs +++ b/crates/rspack_plugin_javascript/src/parser_plugin/provide_plugin.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use itertools::Itertools; use once_cell::sync::OnceCell; use rspack_core::{ @@ -23,7 +24,10 @@ fn create_provide_dep( ) -> Option { if let Some(requests) = value.get(name) { let name_identifier = if name.contains(SOURCE_DOT) { - format!("__webpack_provide_{}", name.replace(SOURCE_DOT, MODULE_DOT)) + format!( + "__webpack_provide_{}", + name.cow_replace(SOURCE_DOT, MODULE_DOT) + ) } else { name.to_string() }; diff --git a/crates/rspack_plugin_json/Cargo.toml b/crates/rspack_plugin_json/Cargo.toml index 01dcafd9fef..662279b5a7c 100644 --- a/crates/rspack_plugin_json/Cargo.toml +++ b/crates/rspack_plugin_json/Cargo.toml @@ -8,6 +8,7 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +cow-utils = { workspace = true } json = { workspace = true } ropey = "1.6.1" rspack_core = { version = "0.1.0", path = "../rspack_core" } diff --git a/crates/rspack_plugin_json/src/lib.rs b/crates/rspack_plugin_json/src/lib.rs index 579dabb52e5..b3eb5d33ee4 100644 --- a/crates/rspack_plugin_json/src/lib.rs +++ b/crates/rspack_plugin_json/src/lib.rs @@ -1,6 +1,7 @@ #![feature(let_chains)] use std::borrow::Cow; +use cow_utils::CowUtils; use json::{ number::Number, object::Object, @@ -174,7 +175,7 @@ impl ParserAndGenerator for JsonParserAndGenerator { let json_expr = if is_js_object && json_str.len() > 20 { Cow::Owned(format!( "JSON.parse('{}')", - json_str.replace('\\', r"\\").replace('\'', r"\'") + json_str.cow_replace('\\', r"\\").cow_replace('\'', r"\'") )) } else { json_str diff --git a/crates/rspack_plugin_lazy_compilation/Cargo.toml b/crates/rspack_plugin_lazy_compilation/Cargo.toml index baec7d8a5ae..85df474193a 100644 --- a/crates/rspack_plugin_lazy_compilation/Cargo.toml +++ b/crates/rspack_plugin_lazy_compilation/Cargo.toml @@ -10,6 +10,7 @@ version = "0.1.0" [dependencies] async-trait = { workspace = true } +cow-utils = { workspace = true } rustc-hash = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } diff --git a/crates/rspack_plugin_lazy_compilation/src/module.rs b/crates/rspack_plugin_lazy_compilation/src/module.rs index a12d595f9c2..0dd5344f526 100644 --- a/crates/rspack_plugin_lazy_compilation/src/module.rs +++ b/crates/rspack_plugin_lazy_compilation/src/module.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use cow_utils::CowUtils; use rspack_collections::Identifiable; use rspack_core::{ impl_module_meta_info, module_namespace_promise, module_update_hash, @@ -260,7 +261,7 @@ impl Module for LazyCompilationProxyModule { .get_module_id(*module) .as_ref() .expect("should have module id") - .replace('"', r#"\""#), + .cow_replace('"', r#"\""#), keep_active, )) } else { diff --git a/crates/rspack_plugin_library/Cargo.toml b/crates/rspack_plugin_library/Cargo.toml index b4c7eccc67d..21ee69f4c2f 100644 --- a/crates/rspack_plugin_library/Cargo.toml +++ b/crates/rspack_plugin_library/Cargo.toml @@ -10,18 +10,17 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -async-trait = { workspace = true } -regex = { workspace = true } -rspack_collections = { version = "0.1.0", path = "../rspack_collections" } -rspack_core = { version = "0.1.0", path = "../rspack_core" } -rspack_error = { version = "0.1.0", path = "../rspack_error" } -rspack_hash = { version = "0.1.0", path = "../rspack_hash" } -rspack_hook = { version = "0.1.0", path = "../rspack_hook" } +async-trait = { workspace = true } +regex = { workspace = true } +rspack_collections = { version = "0.1.0", path = "../rspack_collections" } +rspack_core = { version = "0.1.0", path = "../rspack_core" } +rspack_error = { version = "0.1.0", path = "../rspack_error" } +rspack_hash = { version = "0.1.0", path = "../rspack_hash" } +rspack_hook = { version = "0.1.0", path = "../rspack_hook" } rspack_plugin_javascript = { version = "0.1.0", path = "../rspack_plugin_javascript" } -rspack_util = { version = "0.1.0", path = "../rspack_util" } -rustc-hash = { workspace = true } -serde_json = { workspace = true } -tracing = { workspace = true } +rspack_util = { version = "0.1.0", path = "../rspack_util" } +rustc-hash = { workspace = true } +serde_json = { workspace = true } swc_core = { workspace = true, features = [ "__parser", "__utils", @@ -34,6 +33,7 @@ swc_core = { workspace = true, features = [ "base", "ecma_quote", ] } +tracing = { workspace = true } [package.metadata.cargo-shear] ignored = ["tracing"] diff --git a/crates/rspack_plugin_runtime/Cargo.toml b/crates/rspack_plugin_runtime/Cargo.toml index ca4e3dbd52f..2af26d14fd4 100644 --- a/crates/rspack_plugin_runtime/Cargo.toml +++ b/crates/rspack_plugin_runtime/Cargo.toml @@ -9,6 +9,7 @@ version = "0.1.0" [dependencies] async-trait = { workspace = true } +cow-utils = { workspace = true } indexmap = { workspace = true } itertools = { workspace = true } rspack_collections = { version = "0.1.0", path = "../rspack_collections" } diff --git a/crates/rspack_plugin_runtime/src/runtime_module/chunk_prefetch_preload_function.rs b/crates/rspack_plugin_runtime/src/runtime_module/chunk_prefetch_preload_function.rs index 5251e27e88a..f441656b56e 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/chunk_prefetch_preload_function.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/chunk_prefetch_preload_function.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ impl_runtime_module, @@ -39,8 +40,9 @@ impl RuntimeModule for ChunkPrefetchPreloadFunctionRuntimeModule { Ok( RawSource::from( include_str!("runtime/chunk_prefetch_preload_function.js") - .replace("$RUNTIME_FUNCTION$", &self.runtime_function.to_string()) - .replace("$RUNTIME_HANDLERS$", &self.runtime_handlers.to_string()), + .cow_replace("$RUNTIME_FUNCTION$", &self.runtime_function.to_string()) + .cow_replace("$RUNTIME_HANDLERS$", &self.runtime_handlers.to_string()) + .into_owned(), ) .boxed(), ) diff --git a/crates/rspack_plugin_runtime/src/runtime_module/chunk_prefetch_trigger.rs b/crates/rspack_plugin_runtime/src/runtime_module/chunk_prefetch_trigger.rs index 2efed42be71..47e489d1544 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/chunk_prefetch_trigger.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/chunk_prefetch_trigger.rs @@ -1,5 +1,6 @@ use std::hash::BuildHasherDefault; +use cow_utils::CowUtils; use indexmap::IndexMap; use rspack_collections::Identifier; use rspack_core::{ @@ -32,10 +33,14 @@ impl RuntimeModule for ChunkPrefetchTriggerRuntimeModule { fn generate(&self, _: &Compilation) -> rspack_error::Result { Ok( - RawSource::from(include_str!("runtime/chunk_prefetch_trigger.js").replace( - "$CHUNK_MAP$", - &serde_json::to_string(&self.chunk_map).expect("invalid json tostring"), - )) + RawSource::from( + include_str!("runtime/chunk_prefetch_trigger.js") + .cow_replace( + "$CHUNK_MAP$", + &serde_json::to_string(&self.chunk_map).expect("invalid json tostring"), + ) + .into_owned(), + ) .boxed(), ) } diff --git a/crates/rspack_plugin_runtime/src/runtime_module/chunk_preload_trigger.rs b/crates/rspack_plugin_runtime/src/runtime_module/chunk_preload_trigger.rs index 9acaa5ff21e..58f5948f693 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/chunk_preload_trigger.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/chunk_preload_trigger.rs @@ -1,5 +1,6 @@ use std::hash::BuildHasherDefault; +use cow_utils::CowUtils; use indexmap::IndexMap; use rspack_collections::Identifier; use rspack_core::{ @@ -32,10 +33,14 @@ impl RuntimeModule for ChunkPreloadTriggerRuntimeModule { fn generate(&self, _: &Compilation) -> rspack_error::Result { Ok( - RawSource::from(include_str!("runtime/chunk_preload_trigger.js").replace( - "$CHUNK_MAP$", - &serde_json::to_string(&self.chunk_map).expect("invalid json tostring"), - )) + RawSource::from( + include_str!("runtime/chunk_preload_trigger.js") + .cow_replace( + "$CHUNK_MAP$", + &serde_json::to_string(&self.chunk_map).expect("invalid json tostring"), + ) + .into_owned(), + ) .boxed(), ) } diff --git a/crates/rspack_plugin_runtime/src/runtime_module/ensure_chunk.rs b/crates/rspack_plugin_runtime/src/runtime_module/ensure_chunk.rs index 20e5fd59588..b51a9d9fce4 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/ensure_chunk.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/ensure_chunk.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ impl_runtime_module, @@ -31,14 +32,16 @@ impl RuntimeModule for EnsureChunkRuntimeModule { Ok( RawSource::from( match runtime_requirements.contains(RuntimeGlobals::ENSURE_CHUNK_HANDLERS) { - true => include_str!("runtime/ensure_chunk.js").replace( - "$FETCH_PRIORITY$", - if runtime_requirements.contains(RuntimeGlobals::HAS_FETCH_PRIORITY) { - ", fetchPriority" - } else { - "" - }, - ), + true => include_str!("runtime/ensure_chunk.js") + .cow_replace( + "$FETCH_PRIORITY$", + if runtime_requirements.contains(RuntimeGlobals::HAS_FETCH_PRIORITY) { + ", fetchPriority" + } else { + "" + }, + ) + .into_owned(), false => include_str!("runtime/ensure_chunk_with_inline.js").to_string(), }, ) diff --git a/crates/rspack_plugin_runtime/src/runtime_module/get_full_hash.rs b/crates/rspack_plugin_runtime/src/runtime_module/get_full_hash.rs index d79fb170a5a..1e3a142fb74 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/get_full_hash.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/get_full_hash.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ impl_runtime_module, @@ -26,7 +27,8 @@ impl RuntimeModule for GetFullHashRuntimeModule { Ok( RawSource::from( include_str!("runtime/get_full_hash.js") - .replace("$HASH$", compilation.get_hash().unwrap_or("XXXX")), + .cow_replace("$HASH$", compilation.get_hash().unwrap_or("XXXX")) + .into_owned(), ) .boxed(), ) diff --git a/crates/rspack_plugin_runtime/src/runtime_module/get_trusted_types_policy.rs b/crates/rspack_plugin_runtime/src/runtime_module/get_trusted_types_policy.rs index b2c94982df8..b063ede3486 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/get_trusted_types_policy.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/get_trusted_types_policy.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ impl_runtime_module, @@ -40,7 +41,7 @@ impl RuntimeModule for GetTrustedTypesPolicyRuntimeModule { let create_script = runtime_requirements.contains(RuntimeGlobals::CREATE_SCRIPT); let create_script_url = runtime_requirements.contains(RuntimeGlobals::CREATE_SCRIPT_URL); - let mut result = include_str!("runtime/get_trusted_types_policy.js").replace( + let result = include_str!("runtime/get_trusted_types_policy.js").cow_replace( "$policyName$", &trusted_types.policy_name.clone().unwrap_or_default(), ); @@ -65,8 +66,14 @@ impl RuntimeModule for GetTrustedTypesPolicyRuntimeModule { .to_string(), ); } - result = result.replace("$policyContent$", policy_content.join(",\n").as_ref()); - Ok(RawSource::from(result).boxed()) + Ok( + RawSource::from( + result + .cow_replace("$policyContent$", policy_content.join(",\n").as_ref()) + .into_owned(), + ) + .boxed(), + ) } fn attach(&mut self, chunk: ChunkUkey) { diff --git a/crates/rspack_plugin_runtime/src/runtime_module/import_scripts_chunk_loading.rs b/crates/rspack_plugin_runtime/src/runtime_module/import_scripts_chunk_loading.rs index b36dfc3477f..46b1eade508 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/import_scripts_chunk_loading.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/import_scripts_chunk_loading.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ compile_boolean_matcher, impl_runtime_module, @@ -145,8 +146,9 @@ impl RuntimeModule for ImportScriptsChunkLoadingRuntimeModule { // If chunkId not corresponding chunkName will skip load it. source.add(RawSource::from( include_str!("runtime/import_scripts_chunk_loading.js") - .replace("$BODY$", body.as_str()) - .replace("$CHUNK_LOADING_GLOBAL_EXPR$", &chunk_loading_global_expr), + .cow_replace("$BODY$", body.as_str()) + .cow_replace("$CHUNK_LOADING_GLOBAL_EXPR$", &chunk_loading_global_expr) + .into_owned(), )); } @@ -167,13 +169,14 @@ impl RuntimeModule for ImportScriptsChunkLoadingRuntimeModule { }; source.add(RawSource::from( include_str!("runtime/import_scripts_chunk_loading_with_hmr.js") - .replace("$URL$", &url) - .replace("$globalObject$", &compilation.options.output.global_object) - .replace( + .cow_replace("$URL$", &url) + .cow_replace("$globalObject$", &compilation.options.output.global_object) + .cow_replace( "$hotUpdateGlobal$", &serde_json::to_string(&compilation.options.output.hot_update_global) .expect("failed to serde_json::to_string(hot_update_global)"), - ), + ) + .into_owned(), )); source.add(RawSource::from(generate_javascript_hmr_runtime( "importScripts", diff --git a/crates/rspack_plugin_runtime/src/runtime_module/jsonp_chunk_loading.rs b/crates/rspack_plugin_runtime/src/runtime_module/jsonp_chunk_loading.rs index cb62b9459dc..8f733705a01 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/jsonp_chunk_loading.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/jsonp_chunk_loading.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ compile_boolean_matcher, impl_runtime_module, @@ -99,8 +100,8 @@ impl RuntimeModule for JsonpChunkLoadingRuntimeModule { "installedChunks[chunkId] = 0;".to_string() } else { include_str!("runtime/jsonp_chunk_loading.js") - .replace("$JS_MATCHER$", &js_matcher) - .replace( + .cow_replace("$JS_MATCHER$", &js_matcher) + .cow_replace( "$MATCH_FALLBACK$", if matches!(has_js_matcher, BooleanMatcher::Condition(true)) { "" @@ -108,7 +109,7 @@ impl RuntimeModule for JsonpChunkLoadingRuntimeModule { "else installedChunks[chunkId] = 0;\n" }, ) - .replace( + .cow_replace( "$FETCH_PRIORITY$", if with_fetch_priority { ", fetchPriority" @@ -116,6 +117,7 @@ impl RuntimeModule for JsonpChunkLoadingRuntimeModule { "" }, ) + .into_owned() }; source.add(RawSource::from(format!( @@ -142,8 +144,9 @@ impl RuntimeModule for JsonpChunkLoadingRuntimeModule { }; source.add(RawSource::from( include_str!("runtime/jsonp_chunk_loading_with_prefetch.js") - .replace("$JS_MATCHER$", &js_matcher) - .replace("$CROSS_ORIGIN$", cross_origin.as_str()), + .cow_replace("$JS_MATCHER$", &js_matcher) + .cow_replace("$CROSS_ORIGIN$", cross_origin.as_str()) + .into_owned(), )); } @@ -184,22 +187,24 @@ impl RuntimeModule for JsonpChunkLoadingRuntimeModule { source.add(RawSource::from( include_str!("runtime/jsonp_chunk_loading_with_preload.js") - .replace("$JS_MATCHER$", &js_matcher) - .replace("$CROSS_ORIGIN$", cross_origin.as_str()) - .replace("$SCRIPT_TYPE_LINK_PRE$", script_type_link_pre.as_str()) - .replace("$SCRIPT_TYPE_LINK_POST$", script_type_link_post), + .cow_replace("$JS_MATCHER$", &js_matcher) + .cow_replace("$CROSS_ORIGIN$", cross_origin.as_str()) + .cow_replace("$SCRIPT_TYPE_LINK_PRE$", script_type_link_pre.as_str()) + .cow_replace("$SCRIPT_TYPE_LINK_POST$", script_type_link_post) + .into_owned(), )); } if with_hmr { source.add(RawSource::from( include_str!("runtime/jsonp_chunk_loading_with_hmr.js") - .replace("$GLOBAL_OBJECT$", &compilation.options.output.global_object) - .replace( + .cow_replace("$GLOBAL_OBJECT$", &compilation.options.output.global_object) + .cow_replace( "$HOT_UPDATE_GLOBAL$", &serde_json::to_string(&compilation.options.output.hot_update_global) .expect("failed to serde_json::to_string(hot_update_global)"), - ), + ) + .into_owned(), )); source.add(RawSource::from(generate_javascript_hmr_runtime("jsonp"))); } @@ -223,14 +228,15 @@ impl RuntimeModule for JsonpChunkLoadingRuntimeModule { ); source.add(RawSource::from( include_str!("runtime/jsonp_chunk_loading_with_callback.js") - .replace("$CHUNK_LOADING_GLOBAL_EXPR$", &chunk_loading_global_expr) - .replace( + .cow_replace("$CHUNK_LOADING_GLOBAL_EXPR$", &chunk_loading_global_expr) + .cow_replace( "$WITH_ON_CHUNK_LOAD$", match with_on_chunk_load { true => "return __webpack_require__.O(result);", false => "", }, - ), + ) + .into_owned(), )); } diff --git a/crates/rspack_plugin_runtime/src/runtime_module/load_script.rs b/crates/rspack_plugin_runtime/src/runtime_module/load_script.rs index edcdc6d7119..6c1af750794 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/load_script.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/load_script.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ impl_runtime_module, @@ -84,23 +85,23 @@ impl RuntimeModule for LoadScriptRuntimeModule { Ok(RawSource::from( include_str!("runtime/load_script.js") - .replace( + .cow_replace( "__CROSS_ORIGIN_LOADING_PLACEHOLDER__", &cross_origin_loading, ) - .replace("$URL$", &url) - .replace("$SCRIPT_TYPE$", &script_type) - .replace("$SCRIPT_CHARSET$", &script_charset) - .replace("$CHUNK_LOAD_TIMEOUT$", &compilation.options.output.chunk_load_timeout.to_string()) - .replace("$CHUNK_LOAD_TIMEOUT_IN_SECONDS$", &compilation.options.output.chunk_load_timeout.saturating_div(1000).to_string()) - .replace( + .cow_replace("$URL$", &url) + .cow_replace("$SCRIPT_TYPE$", &script_type) + .cow_replace("$SCRIPT_CHARSET$", &script_charset) + .cow_replace("$CHUNK_LOAD_TIMEOUT$", &compilation.options.output.chunk_load_timeout.to_string()) + .cow_replace("$CHUNK_LOAD_TIMEOUT_IN_SECONDS$", &compilation.options.output.chunk_load_timeout.saturating_div(1000).to_string()) + .cow_replace( "$UNIQUE_GET_ATTRIBUTE$", match unique_prefix { Some(_) => r#"s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key"#, None => r#"s.getAttribute("src") == url"#, }, ) - .replace("$FETCH_PRIORITY_SET_ATTRIBUTE$", if with_fetch_priority { + .cow_replace("$FETCH_PRIORITY_SET_ATTRIBUTE$", if with_fetch_priority { r#" if(fetchPriority) { script.setAttribute("fetchpriority", fetchPriority); @@ -109,22 +110,22 @@ impl RuntimeModule for LoadScriptRuntimeModule { } else { "" }) - .replace("$FETCH_PRIORITY$", if with_fetch_priority { + .cow_replace("$FETCH_PRIORITY$", if with_fetch_priority { ", fetchPriority" } else { "" }) - .replace( + .cow_replace( "$UNIQUE_SET_ATTRIBUTE$", match unique_prefix { Some(_) => r#"script.setAttribute("data-webpack", dataWebpackPrefix + key);"#, None => "", }, ) - .replace( + .cow_replace( "$UNIQUE_PREFIX$", unique_prefix.unwrap_or_default().as_str(), - ), + ).into_owned(), ) .boxed()) } diff --git a/crates/rspack_plugin_runtime/src/runtime_module/module_chunk_loading.rs b/crates/rspack_plugin_runtime/src/runtime_module/module_chunk_loading.rs index 1f4b6df4959..417372e0443 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/module_chunk_loading.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/module_chunk_loading.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ compile_boolean_matcher, impl_runtime_module, @@ -101,13 +102,15 @@ impl RuntimeModule for ModuleChunkLoadingRuntimeModule { if with_loading || with_external_install_chunk { source.add(RawSource::from( - include_str!("runtime/module_chunk_loading.js").replace( - "$WITH_ON_CHUNK_LOAD$", - match with_on_chunk_load { - true => "__webpack_require__.O();", - false => "", - }, - ), + include_str!("runtime/module_chunk_loading.js") + .cow_replace( + "$WITH_ON_CHUNK_LOAD$", + match with_on_chunk_load { + true => "__webpack_require__.O();", + false => "", + }, + ) + .into_owned(), )); } @@ -116,13 +119,13 @@ impl RuntimeModule for ModuleChunkLoadingRuntimeModule { "installedChunks[chunkId] = 0;".to_string() } else { include_str!("runtime/module_chunk_loading_with_loading.js") - .replace("$JS_MATCHER$", &has_js_matcher.render("chunkId")) - .replace( + .cow_replace("$JS_MATCHER$", &has_js_matcher.render("chunkId")) + .cow_replace( "$IMPORT_FUNCTION_NAME$", &compilation.options.output.import_function_name, ) - .replace("$OUTPUT_DIR$", &root_output_dir) - .replace( + .cow_replace("$OUTPUT_DIR$", &root_output_dir) + .cow_replace( "$MATCH_FALLBACK$", if matches!(has_js_matcher, BooleanMatcher::Condition(true)) { "" @@ -130,6 +133,7 @@ impl RuntimeModule for ModuleChunkLoadingRuntimeModule { "else installedChunks[chunkId] = 0;\n" }, ) + .into_owned() }; source.add(RawSource::from(format!( diff --git a/crates/rspack_plugin_runtime/src/runtime_module/public_path.rs b/crates/rspack_plugin_runtime/src/runtime_module/public_path.rs index 23274402e49..a983917cb54 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/public_path.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/public_path.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ has_hash_placeholder, impl_runtime_module, @@ -25,10 +26,14 @@ impl RuntimeModule for PublicPathRuntimeModule { fn generate(&self, compilation: &Compilation) -> rspack_error::Result { Ok( - RawSource::from(include_str!("runtime/public_path.js").replace( - "__PUBLIC_PATH_PLACEHOLDER__", - &PublicPath::render_filename(compilation, &self.public_path), - )) + RawSource::from( + include_str!("runtime/public_path.js") + .cow_replace( + "__PUBLIC_PATH_PLACEHOLDER__", + &PublicPath::render_filename(compilation, &self.public_path), + ) + .into_owned(), + ) .boxed(), ) } diff --git a/crates/rspack_plugin_runtime/src/runtime_module/readfile_chunk_loading.rs b/crates/rspack_plugin_runtime/src/runtime_module/readfile_chunk_loading.rs index 3fb47a17678..e23fc22fd88 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/readfile_chunk_loading.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/readfile_chunk_loading.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ compile_boolean_matcher, impl_runtime_module, @@ -114,13 +115,15 @@ impl RuntimeModule for ReadFileChunkLoadingRuntimeModule { if with_loading || with_external_install_chunk { source.add(RawSource::from( - include_str!("runtime/readfile_chunk_loading.js").replace( - "$WITH_ON_CHUNK_LOADED$", - match with_on_chunk_load { - true => "__webpack_require__.O();", - false => "", - }, - ), + include_str!("runtime/readfile_chunk_loading.js") + .cow_replace( + "$WITH_ON_CHUNK_LOADED$", + match with_on_chunk_load { + true => "__webpack_require__.O();", + false => "", + }, + ) + .into_owned(), )); } @@ -129,9 +132,9 @@ impl RuntimeModule for ReadFileChunkLoadingRuntimeModule { "installedChunks[chunkId] = 0;".to_string() } else { include_str!("runtime/readfile_chunk_loading_with_loading.js") - .replace("$JS_MATCHER$", &has_js_matcher.render("chunkId")) - .replace("$OUTPUT_DIR$", &root_output_dir) - .replace( + .cow_replace("$JS_MATCHER$", &has_js_matcher.render("chunkId")) + .cow_replace("$OUTPUT_DIR$", &root_output_dir) + .cow_replace( "$MATCH_FALLBACK$", if matches!(has_js_matcher, BooleanMatcher::Condition(true)) { "" @@ -139,6 +142,7 @@ impl RuntimeModule for ReadFileChunkLoadingRuntimeModule { "else installedChunks[chunkId] = 0;\n" }, ) + .into_owned() }; source.add(RawSource::from(format!( @@ -169,7 +173,8 @@ impl RuntimeModule for ReadFileChunkLoadingRuntimeModule { if with_hmr_manifest { source.add(RawSource::from( include_str!("runtime/readfile_chunk_loading_with_hmr_manifest.js") - .replace("$OUTPUT_DIR$", &root_output_dir), + .cow_replace("$OUTPUT_DIR$", &root_output_dir) + .into_owned(), )); } diff --git a/crates/rspack_plugin_runtime/src/runtime_module/require_js_chunk_loading.rs b/crates/rspack_plugin_runtime/src/runtime_module/require_js_chunk_loading.rs index c42eb6e9318..f2ead4775df 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/require_js_chunk_loading.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/require_js_chunk_loading.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ compile_boolean_matcher, impl_runtime_module, @@ -115,13 +116,15 @@ impl RuntimeModule for RequireChunkLoadingRuntimeModule { if with_loading || with_external_install_chunk { source.add(RawSource::from( - include_str!("runtime/require_chunk_loading.js").replace( - "$WITH_ON_CHUNK_LOADED$", - match with_on_chunk_load { - true => "__webpack_require__.O();", - false => "", - }, - ), + include_str!("runtime/require_chunk_loading.js") + .cow_replace( + "$WITH_ON_CHUNK_LOADED$", + match with_on_chunk_load { + true => "__webpack_require__.O();", + false => "", + }, + ) + .into_owned(), )); } @@ -139,8 +142,9 @@ impl RuntimeModule for RequireChunkLoadingRuntimeModule { } else { source.add(RawSource::from( include_str!("runtime/require_chunk_loading_with_loading.js") - .replace("$JS_MATCHER$", &has_js_matcher.render("chunkId")) - .replace("$OUTPUT_DIR$", &root_output_dir), + .cow_replace("$JS_MATCHER$", &has_js_matcher.render("chunkId")) + .cow_replace("$OUTPUT_DIR$", &root_output_dir) + .into_owned(), )); } } diff --git a/crates/rspack_plugin_runtime/src/runtime_module/rspack_unique_id.rs b/crates/rspack_plugin_runtime/src/runtime_module/rspack_unique_id.rs index f3bdf4b01ee..c7be075ab15 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/rspack_unique_id.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/rspack_unique_id.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ impl_runtime_module, @@ -35,8 +36,9 @@ impl RuntimeModule for RspackUniqueIdRuntimeModule { Ok( RawSource::from( include_str!("runtime/get_unique_id.js") - .replace("$BUNDLER_NAME$", &self.bundler_name) - .replace("$BUNDLER_VERSION$", &self.bundler_version), + .cow_replace("$BUNDLER_NAME$", &self.bundler_name) + .cow_replace("$BUNDLER_VERSION$", &self.bundler_version) + .into_owned(), ) .boxed(), ) diff --git a/crates/rspack_plugin_runtime/src/runtime_module/rspack_version.rs b/crates/rspack_plugin_runtime/src/runtime_module/rspack_version.rs index 868c4ace085..53be16341cf 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/rspack_version.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/rspack_version.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::{ impl_runtime_module, @@ -25,8 +26,12 @@ impl RuntimeModule for RspackVersionRuntimeModule { fn generate(&self, _: &Compilation) -> rspack_error::Result { Ok( - RawSource::from(include_str!("runtime/get_version.js").replace("$VERSION$", &self.version)) - .boxed(), + RawSource::from( + include_str!("runtime/get_version.js") + .cow_replace("$VERSION$", &self.version) + .into_owned(), + ) + .boxed(), ) } } diff --git a/crates/rspack_plugin_runtime/src/runtime_module/utils.rs b/crates/rspack_plugin_runtime/src/runtime_module/utils.rs index b24c0e374b2..ea27788dc31 100644 --- a/crates/rspack_plugin_runtime/src/runtime_module/utils.rs +++ b/crates/rspack_plugin_runtime/src/runtime_module/utils.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use itertools::Itertools; use rspack_collections::{UkeyIndexMap, UkeyIndexSet}; use rspack_core::{ @@ -268,10 +269,11 @@ fn test_get_undo_path() { pub fn generate_javascript_hmr_runtime(method: &str) -> String { include_str!("runtime/javascript_hot_module_replacement.js") - .replace("$key$", method) - .replace("$HOT_TEST_OUTDATED$", &HOT_TEST_OUTDATED) - .replace("$HOT_TEST_DISPOSE$", &HOT_TEST_DISPOSE) - .replace("$HOT_TEST_UPDATED$", &HOT_TEST_UPDATED) - .replace("$HOT_TEST_RUNTIME$", &HOT_TEST_RUNTIME) - .replace("$HOT_TEST_ACCEPT$", &HOT_TEST_ACCEPT) + .cow_replace("$key$", method) + .cow_replace("$HOT_TEST_OUTDATED$", &HOT_TEST_OUTDATED) + .cow_replace("$HOT_TEST_DISPOSE$", &HOT_TEST_DISPOSE) + .cow_replace("$HOT_TEST_UPDATED$", &HOT_TEST_UPDATED) + .cow_replace("$HOT_TEST_RUNTIME$", &HOT_TEST_RUNTIME) + .cow_replace("$HOT_TEST_ACCEPT$", &HOT_TEST_ACCEPT) + .into_owned() } diff --git a/crates/rspack_plugin_swc_js_minimizer/Cargo.toml b/crates/rspack_plugin_swc_js_minimizer/Cargo.toml index c6fb37236ea..01cbb0f3eb7 100644 --- a/crates/rspack_plugin_swc_js_minimizer/Cargo.toml +++ b/crates/rspack_plugin_swc_js_minimizer/Cargo.toml @@ -9,6 +9,7 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +cow-utils = { workspace = true } once_cell = { workspace = true } rayon = { workspace = true } regex = { workspace = true } diff --git a/crates/rspack_plugin_swc_js_minimizer/src/lib.rs b/crates/rspack_plugin_swc_js_minimizer/src/lib.rs index 38b7d6ebd65..3a407eedb5d 100644 --- a/crates/rspack_plugin_swc_js_minimizer/src/lib.rs +++ b/crates/rspack_plugin_swc_js_minimizer/src/lib.rs @@ -7,6 +7,7 @@ use std::hash::Hash; use std::path::Path; use std::sync::{mpsc, LazyLock, Mutex}; +use cow_utils::CowUtils; use once_cell::sync::OnceCell; use rayon::prelude::*; use regex::Regex; @@ -214,7 +215,8 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { let banner = match &extract_comments.banner { OptionWrapper::Default => { let dir = Path::new(filename).parent().expect("should has parent"); - let relative = Path::new(&comments_filename).strip_prefix(dir).expect("should has common prefix").to_string_lossy().to_string().replace('\\', "/"); + let raw = Path::new(&comments_filename).strip_prefix(dir).expect("should has common prefix").to_string_lossy(); + let relative = raw.cow_replace('\\', "/"); Some(format!("/*! For license information please see {relative} */")) }, OptionWrapper::Disabled => None, diff --git a/crates/rspack_plugin_warn_sensitive_module/Cargo.toml b/crates/rspack_plugin_warn_sensitive_module/Cargo.toml index f8befc845cf..d07c3c7e188 100644 --- a/crates/rspack_plugin_warn_sensitive_module/Cargo.toml +++ b/crates/rspack_plugin_warn_sensitive_module/Cargo.toml @@ -7,6 +7,7 @@ repository = "https://github.com/web-infra-dev/rspack" version = "0.1.0" [dependencies] +cow-utils = { workspace = true } rspack_collections = { version = "0.1.0", path = "../rspack_collections" } rspack_core = { version = "0.1.0", path = "../rspack_core" } rspack_error = { version = "0.1.0", path = "../rspack_error" } diff --git a/crates/rspack_plugin_warn_sensitive_module/src/lib.rs b/crates/rspack_plugin_warn_sensitive_module/src/lib.rs index b27e0398457..e6f66126783 100644 --- a/crates/rspack_plugin_warn_sensitive_module/src/lib.rs +++ b/crates/rspack_plugin_warn_sensitive_module/src/lib.rs @@ -2,6 +2,7 @@ use std::{collections::HashMap, hash::BuildHasherDefault}; +use cow_utils::CowUtils; use rspack_collections::{Identifier, IdentifierSet}; use rspack_core::{ ApplyContext, Compilation, CompilationSeal, CompilerOptions, Logger, ModuleGraph, Plugin, @@ -69,16 +70,16 @@ async fn seal(&self, compilation: &mut Compilation) -> Result<()> { } let identifier = module.identifier(); - let lower_identifier = identifier.to_lowercase(); - if let Some(prev_identifier) = not_conflect.remove(&lower_identifier) { + let lower_identifier = identifier.cow_to_lowercase(); + if let Some(prev_identifier) = not_conflect.remove(lower_identifier.as_ref()) { conflict.insert( - lower_identifier, + lower_identifier.into_owned(), IdentifierSet::from_iter([prev_identifier, identifier]), ); - } else if let Some(set) = conflict.get_mut(&lower_identifier) { + } else if let Some(set) = conflict.get_mut(lower_identifier.as_ref()) { set.insert(identifier); } else { - not_conflect.insert(lower_identifier, identifier); + not_conflect.insert(lower_identifier.into_owned(), identifier); } } diff --git a/crates/rspack_plugin_wasm/Cargo.toml b/crates/rspack_plugin_wasm/Cargo.toml index f7241adb5e5..191ddbfd0ed 100644 --- a/crates/rspack_plugin_wasm/Cargo.toml +++ b/crates/rspack_plugin_wasm/Cargo.toml @@ -10,6 +10,7 @@ version = "0.1.0" [dependencies] async-trait = { workspace = true } +cow-utils = { workspace = true } dashmap = { workspace = true } indexmap = { workspace = true } rayon = { workspace = true } diff --git a/crates/rspack_plugin_wasm/src/runtime.rs b/crates/rspack_plugin_wasm/src/runtime.rs index ea28c2e58b9..4404c20b8bd 100644 --- a/crates/rspack_plugin_wasm/src/runtime.rs +++ b/crates/rspack_plugin_wasm/src/runtime.rs @@ -1,3 +1,4 @@ +use cow_utils::CowUtils; use rspack_collections::Identifier; use rspack_core::rspack_sources::{BoxSource, RawSource, SourceExt}; use rspack_core::{ @@ -63,8 +64,8 @@ impl RuntimeModule for AsyncWasmLoadingRuntimeModule { RawSource::from(get_async_wasm_loading( &self .generate_load_binary_code - .replace("$PATH", &format!("\"{}\"", path)) - .replace( + .cow_replace("$PATH", &format!("\"{}\"", path)) + .cow_replace( "$IMPORT_META_NAME", compilation.options.output.import_meta_name.as_str(), ), diff --git a/crates/rspack_regex/Cargo.toml b/crates/rspack_regex/Cargo.toml index 98558885a9e..c8edf3807de 100644 --- a/crates/rspack_regex/Cargo.toml +++ b/crates/rspack_regex/Cargo.toml @@ -9,6 +9,7 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +cow-utils = { workspace = true } regex-syntax = { version = "0.8.3", default-features = false, features = ["std"] } regress = "0.10.0" rspack_error = { version = "0.1.0", path = "../rspack_error" } diff --git a/crates/rspack_regex/src/lib.rs b/crates/rspack_regex/src/lib.rs index 4434936723a..b2384041e71 100644 --- a/crates/rspack_regex/src/lib.rs +++ b/crates/rspack_regex/src/lib.rs @@ -2,6 +2,7 @@ use std::fmt::Debug; +use cow_utils::CowUtils; use rspack_error::Error; use swc_core::ecma::ast::Regex as SwcRegex; @@ -72,8 +73,9 @@ impl RspackRegex { } else { self.to_source_string() } - .replace('!', "%21") - .replace('|', "%7C") + .cow_replace('!', "%21") + .cow_replace('|', "%7C") + .into_owned() } } diff --git a/crates/swc_plugin_import/Cargo.toml b/crates/swc_plugin_import/Cargo.toml index 5fbe3b73dab..ec0367089d8 100644 --- a/crates/swc_plugin_import/Cargo.toml +++ b/crates/swc_plugin_import/Cargo.toml @@ -6,6 +6,7 @@ name = "swc_plugin_import" version = "0.1.5" [dependencies] +cow-utils = { workspace = true } handlebars = "5.1.2" heck = { workspace = true } rustc-hash = { workspace = true } diff --git a/crates/swc_plugin_import/src/lib.rs b/crates/swc_plugin_import/src/lib.rs index 5f82dc9afec..75c4fdc7018 100644 --- a/crates/swc_plugin_import/src/lib.rs +++ b/crates/swc_plugin_import/src/lib.rs @@ -5,6 +5,7 @@ mod visit; use std::fmt::Debug; +use cow_utils::CowUtils; use handlebars::{Context, Helper, HelperResult, Output, RenderContext, Template}; use heck::{ToKebabCase, ToLowerCamelCase, ToSnakeCase}; use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet}; @@ -261,7 +262,7 @@ pub fn plugin_import(config: &Vec) -> impl Fold + '_ { .param(0) .and_then(|v| v.value().as_str()) .unwrap_or(""); - out.write(param.to_uppercase().as_ref())?; + out.write(param.cow_to_uppercase().as_ref())?; Ok(()) }, ), @@ -280,7 +281,7 @@ pub fn plugin_import(config: &Vec) -> impl Fold + '_ { .param(0) .and_then(|v| v.value().as_str()) .unwrap_or(""); - out.write(param.to_lowercase().as_ref())?; + out.write(param.cow_to_lowercase().as_ref())?; Ok(()) }, ),