Skip to content

Commit

Permalink
feat(plugin-asset): support generator['asset'].importMode for Rslib (
Browse files Browse the repository at this point in the history
…#8724)

* chore: update

* test: update snapshot

* test: update snapshot

* chore: update comment
  • Loading branch information
SoonIter authored Jan 20, 2025
1 parent 2165f1b commit 33654c7
Show file tree
Hide file tree
Showing 28 changed files with 616 additions and 143 deletions.
2 changes: 2 additions & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,7 @@ export interface RawAssetGeneratorOptions {
outputPath?: JsFilename
publicPath?: "auto" | JsFilename
dataUrl?: RawAssetGeneratorDataUrlOptions | ((source: Buffer, context: RawAssetGeneratorDataUrlFnCtx) => string)
importMode?: "url" | "preserve"
}

export interface RawAssetInlineGeneratorOptions {
Expand All @@ -1175,6 +1176,7 @@ export interface RawAssetResourceGeneratorOptions {
filename?: JsFilename
outputPath?: JsFilename
publicPath?: "auto" | JsFilename
importMode?: "url" | "preserve"
}

export interface RawBannerPluginOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,9 @@ pub struct RawAssetGeneratorOptions {
ts_type = "RawAssetGeneratorDataUrlOptions | ((source: Buffer, context: RawAssetGeneratorDataUrlFnCtx) => string)"
)]
pub data_url: Option<RawAssetGeneratorDataUrl>,

#[napi(ts_type = r#""url" | "preserve""#)]
pub import_mode: Option<String>,
}

impl From<RawAssetGeneratorOptions> for AssetGeneratorOptions {
Expand All @@ -553,6 +556,7 @@ impl From<RawAssetGeneratorOptions> for AssetGeneratorOptions {
data_url: value
.data_url
.map(|i| RawAssetGeneratorDataUrlWrapper(i).into()),
import_mode: value.import_mode.map(|n| n.into()),
}
}
}
Expand Down Expand Up @@ -585,6 +589,8 @@ pub struct RawAssetResourceGeneratorOptions {
pub output_path: Option<JsFilename>,
#[napi(ts_type = "\"auto\" | JsFilename")]
pub public_path: Option<JsFilename>,
#[napi(ts_type = r#""url" | "preserve""#)]
pub import_mode: Option<String>,
}

impl From<RawAssetResourceGeneratorOptions> for AssetResourceGeneratorOptions {
Expand All @@ -594,6 +600,7 @@ impl From<RawAssetResourceGeneratorOptions> for AssetResourceGeneratorOptions {
filename: value.filename.map(|i| i.into()),
output_path: value.output_path.map(|i| i.into()),
public_path: value.public_path.map(|i| i.into()),
import_mode: value.import_mode.map(|i| i.into()),
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions crates/rspack_core/src/artifacts/code_generation_results.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ impl CodeGenerationDataUrl {
}
}

// For performance, mark the js modules containing AUTO_PUBLIC_PATH_PLACEHOLDER
#[derive(Clone, Debug)]
pub struct CodeGenerationPublicPathAutoReplace(pub bool);

#[derive(Clone, Debug)]
pub struct CodeGenerationDataFilename {
filename: String,
Expand Down
37 changes: 30 additions & 7 deletions crates/rspack_core/src/concatenated_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ use crate::{
subtract_runtime_condition, to_identifier, AsyncDependenciesBlockIdentifier, BoxDependency,
BuildContext, BuildInfo, BuildMeta, BuildMetaDefaultObject, BuildMetaExportsType, BuildResult,
ChunkGraph, ChunkInitFragments, CodeGenerationDataTopLevelDeclarations,
CodeGenerationExportsFinalNames, CodeGenerationResult, Compilation, ConcatenatedModuleIdent,
ConcatenationScope, ConnectionState, Context, DependenciesBlock, DependencyId,
DependencyTemplate, DependencyType, ErrorSpan, ExportInfoProvided, ExportsArgument, ExportsType,
FactoryMeta, IdentCollector, LibIdentOptions, MaybeDynamicTargetExportInfoHashKey, Module,
ModuleDependency, ModuleGraph, ModuleGraphConnection, ModuleIdentifier, ModuleLayer, ModuleType,
Resolve, RuntimeCondition, RuntimeGlobals, RuntimeSpec, SourceType, SpanExt, Template,
UsageState, UsedName, DEFAULT_EXPORT, NAMESPACE_OBJECT_EXPORT,
CodeGenerationExportsFinalNames, CodeGenerationPublicPathAutoReplace, CodeGenerationResult,
Compilation, ConcatenatedModuleIdent, ConcatenationScope, ConnectionState, Context,
DependenciesBlock, DependencyId, DependencyTemplate, DependencyType, ErrorSpan,
ExportInfoProvided, ExportsArgument, ExportsType, FactoryMeta, IdentCollector, LibIdentOptions,
MaybeDynamicTargetExportInfoHashKey, Module, ModuleDependency, ModuleGraph,
ModuleGraphConnection, ModuleIdentifier, ModuleLayer, ModuleType, Resolve, RuntimeCondition,
RuntimeGlobals, RuntimeSpec, SourceType, SpanExt, Template, UsageState, UsedName, DEFAULT_EXPORT,
NAMESPACE_OBJECT_EXPORT,
};

type ExportsDefinitionArgs = Vec<(String, String)>;
Expand Down Expand Up @@ -193,6 +194,8 @@ pub struct ConcatenatedModuleInfo {
pub global_scope_ident: Vec<ConcatenatedModuleIdent>,
pub idents: Vec<ConcatenatedModuleIdent>,
pub binding_to_ref: HashMap<(Atom, SyntaxContext), Vec<ConcatenatedModuleIdent>>,

pub public_path_auto_replace: Option<bool>,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -672,6 +675,7 @@ impl Module for ConcatenatedModule {

let mut all_used_names: HashSet<Atom> = RESERVED_NAMES.iter().map(|s| Atom::new(*s)).collect();
let mut top_level_declarations: HashSet<Atom> = HashSet::default();
let mut public_path_auto_replace: bool = false;

for module_info_id in modules_with_info.iter() {
let Some(ModuleInfo::Concatenated(info)) = module_to_info_map.get_mut(module_info_id) else {
Expand Down Expand Up @@ -800,6 +804,11 @@ impl Module for ConcatenatedModule {
info.namespace_object_name = Some(namespace_object_name.clone());
top_level_declarations.insert(namespace_object_name);
}

// Handle publicPathAutoReplace for perf
if let Some(info_auto) = info.public_path_auto_replace {
public_path_auto_replace = public_path_auto_replace || info_auto;
}
}

// Handle external type
Expand Down Expand Up @@ -1288,6 +1297,13 @@ impl Module for ConcatenatedModule {
code_generation_result.add(SourceType::JavaScript, CachedSource::new(result).boxed());
code_generation_result.chunk_init_fragments = chunk_init_fragments;
code_generation_result.runtime_requirements = runtime_requirements;

if public_path_auto_replace {
code_generation_result
.data
.insert(CodeGenerationPublicPathAutoReplace(true));
}

code_generation_result
.data
.insert(CodeGenerationDataTopLevelDeclarations::new(
Expand Down Expand Up @@ -1701,6 +1717,7 @@ impl ConcatenatedModule {
.module_by_identifier(&module_id)
.unwrap_or_else(|| panic!("should have module {module_id}"));
let codegen_res = module.code_generation(compilation, runtime, Some(concatenation_scope))?;

let CodeGenerationResult {
mut inner,
mut chunk_init_fragments,
Expand Down Expand Up @@ -1779,6 +1796,12 @@ impl ConcatenatedModule {
module_info.internal_source = Some(source);
module_info.source = Some(result_source);
module_info.chunk_init_fragments = chunk_init_fragments;
if let Some(CodeGenerationPublicPathAutoReplace(true)) = codegen_res
.data
.get::<CodeGenerationPublicPathAutoReplace>(
) {
module_info.public_path_auto_replace = Some(true);
}
Ok(ModuleInfo::Concatenated(Box::new(module_info)))
} else {
Ok(info)
Expand Down
42 changes: 42 additions & 0 deletions crates/rspack_core/src/options/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,13 +472,53 @@ impl From<AssetGeneratorOptions> for AssetInlineGeneratorOptions {
}
}

#[cacheable]
#[derive(Debug, Clone, Copy, MergeFrom)]
struct AssetGeneratorImportModeFlags(u8);
bitflags! {
impl AssetGeneratorImportModeFlags: u8 {
const URL = 1 << 0;
const PRESERVE = 1 << 1;
}
}

#[cacheable]
#[derive(Debug, Clone, Copy, MergeFrom)]
pub struct AssetGeneratorImportMode(AssetGeneratorImportModeFlags);

impl AssetGeneratorImportMode {
pub fn is_url(&self) -> bool {
self.0.contains(AssetGeneratorImportModeFlags::URL)
}
pub fn is_preserve(&self) -> bool {
self.0.contains(AssetGeneratorImportModeFlags::PRESERVE)
}
}

impl From<String> for AssetGeneratorImportMode {
fn from(s: String) -> Self {
match s.as_str() {
"url" => Self(AssetGeneratorImportModeFlags::URL),
"preserve" => Self(AssetGeneratorImportModeFlags::PRESERVE),
_ => unreachable!("AssetGeneratorImportMode error"),
}
}
}

impl Default for AssetGeneratorImportMode {
fn default() -> Self {
Self(AssetGeneratorImportModeFlags::URL)
}
}

#[cacheable]
#[derive(Debug, Clone, MergeFrom)]
pub struct AssetResourceGeneratorOptions {
pub emit: Option<bool>,
pub filename: Option<Filename>,
pub output_path: Option<Filename>,
pub public_path: Option<PublicPath>,
pub import_mode: Option<AssetGeneratorImportMode>,
}

impl From<AssetGeneratorOptions> for AssetResourceGeneratorOptions {
Expand All @@ -488,6 +528,7 @@ impl From<AssetGeneratorOptions> for AssetResourceGeneratorOptions {
filename: value.filename,
output_path: value.output_path,
public_path: value.public_path,
import_mode: value.import_mode,
}
}
}
Expand All @@ -500,6 +541,7 @@ pub struct AssetGeneratorOptions {
pub output_path: Option<Filename>,
pub public_path: Option<PublicPath>,
pub data_url: Option<AssetGeneratorDataUrl>,
pub import_mode: Option<AssetGeneratorImportMode>,
}

pub struct AssetGeneratorDataUrlFnCtx<'a> {
Expand Down
24 changes: 12 additions & 12 deletions crates/rspack_plugin_asset/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ version = "0.2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
async-trait = { workspace = true }
mime_guess = { workspace = true }
rayon = { workspace = true }
rspack_base64 = { workspace = true }
async-trait = { workspace = true }
mime_guess = { workspace = true }
rayon = { workspace = true }
rspack_base64 = { workspace = true }
rspack_cacheable = { workspace = true }
rspack_core = { workspace = true }
rspack_error = { workspace = true }
rspack_hash = { workspace = true }
rspack_hook = { workspace = true }
rspack_util = { workspace = true }
serde_json = { workspace = true }
tracing = { workspace = true }
urlencoding = { workspace = true }
rspack_core = { workspace = true }
rspack_error = { workspace = true }
rspack_hash = { workspace = true }
rspack_hook = { workspace = true }
rspack_util = { workspace = true }
serde_json = { workspace = true }
tracing = { workspace = true }
urlencoding = { workspace = true }

[package.metadata.cargo-shear]
ignored = ["tracing"]
65 changes: 65 additions & 0 deletions crates/rspack_plugin_asset/src/asset_exports_dependency.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use rspack_cacheable::{cacheable, cacheable_dyn};
use rspack_core::{
AsContextDependency, AsModuleDependency, Compilation, Dependency, DependencyId,
DependencyTemplate, ExportNameOrSpec, ExportsOfExportsSpec, ExportsSpec, ModuleGraph,
RuntimeSpec, TemplateContext, TemplateReplaceSource,
};

#[cacheable]
#[derive(Debug, Clone, Default)]
pub struct AssetExportsDependency {
id: DependencyId,
}

impl AssetExportsDependency {
pub fn new() -> Self {
Self {
id: DependencyId::new(),
}
}
}

#[cacheable_dyn]
impl Dependency for AssetExportsDependency {
fn id(&self) -> &rspack_core::DependencyId {
&self.id
}

fn get_exports(&self, _mg: &ModuleGraph) -> Option<ExportsSpec> {
Some(ExportsSpec {
exports: ExportsOfExportsSpec::Array(vec![ExportNameOrSpec::String("default".into())]),
priority: Some(1),
terminal_binding: Some(true),
..Default::default()
})
}

fn could_affect_referencing_module(&self) -> rspack_core::AffectType {
rspack_core::AffectType::False
}
}

impl AsModuleDependency for AssetExportsDependency {}
impl AsContextDependency for AssetExportsDependency {}

#[cacheable_dyn]
impl DependencyTemplate for AssetExportsDependency {
fn apply(
&self,
_source: &mut TemplateReplaceSource,
_code_generatable_context: &mut TemplateContext,
) {
}

fn dependency_id(&self) -> Option<DependencyId> {
Some(self.id)
}

fn update_hash(
&self,
_hasher: &mut dyn std::hash::Hasher,
_compilation: &Compilation,
_runtime: Option<&RuntimeSpec>,
) {
}
}
Loading

2 comments on commit 33654c7

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented on 33654c7 Jan 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Benchmark detail: Open

Name Base (2025-01-20 1d58294) Current Change
10000_big_production-mode_disable-minimize + exec 37.8 s ± 901 ms 38.9 s ± 1.05 s +3.02 %
10000_development-mode + exec 1.82 s ± 16 ms 1.85 s ± 104 ms +1.28 %
10000_development-mode_hmr + exec 680 ms ± 6.2 ms 690 ms ± 29 ms +1.56 %
10000_production-mode + exec 2.39 s ± 24 ms 2.48 s ± 210 ms +3.89 %
10000_production-mode_persistent-cold + exec 2.57 s ± 130 ms 2.52 s ± 24 ms -2.02 %
10000_production-mode_persistent-hot + exec 1.76 s ± 31 ms 1.75 s ± 10 ms -0.83 %
arco-pro_development-mode + exec 1.76 s ± 87 ms 1.75 s ± 125 ms -0.46 %
arco-pro_development-mode_hmr + exec 388 ms ± 3.7 ms 386 ms ± 2 ms -0.50 %
arco-pro_production-mode + exec 3.74 s ± 79 ms 3.68 s ± 73 ms -1.43 %
arco-pro_production-mode_generate-package-json-webpack-plugin + exec 3.79 s ± 53 ms 3.78 s ± 133 ms -0.41 %
arco-pro_production-mode_persistent-cold + exec 3.89 s ± 129 ms 3.81 s ± 99 ms -2.16 %
arco-pro_production-mode_persistent-hot + exec 2.46 s ± 63 ms 2.51 s ± 120 ms +2.24 %
arco-pro_production-mode_traverse-chunk-modules + exec 3.78 s ± 165 ms 3.77 s ± 124 ms -0.05 %
large-dyn-imports_development-mode + exec 2.09 s ± 55 ms 2.12 s ± 258 ms +1.43 %
large-dyn-imports_production-mode + exec 2.15 s ± 48 ms 2.12 s ± 16 ms -1.29 %
threejs_development-mode_10x + exec 1.61 s ± 14 ms 1.52 s ± 16 ms -5.50 %
threejs_development-mode_10x_hmr + exec 770 ms ± 22 ms 783 ms ± 6.2 ms +1.71 %
threejs_production-mode_10x + exec 5.55 s ± 241 ms 5.42 s ± 314 ms -2.27 %
threejs_production-mode_10x_persistent-cold + exec 5.62 s ± 323 ms 5.53 s ± 282 ms -1.70 %
threejs_production-mode_10x_persistent-hot + exec 4.74 s ± 234 ms 4.7 s ± 112 ms -0.83 %
10000_big_production-mode_disable-minimize + rss memory 8691 MiB ± 16 MiB 8696 MiB ± 22.6 MiB +0.06 %
10000_development-mode + rss memory 647 MiB ± 15.8 MiB 655 MiB ± 36.8 MiB +1.29 %
10000_development-mode_hmr + rss memory 1240 MiB ± 178 MiB 1242 MiB ± 242 MiB +0.17 %
10000_production-mode + rss memory 628 MiB ± 22.8 MiB 646 MiB ± 27.4 MiB +2.90 %
10000_production-mode_persistent-cold + rss memory 746 MiB ± 13.1 MiB 752 MiB ± 22.7 MiB +0.79 %
10000_production-mode_persistent-hot + rss memory 730 MiB ± 23.5 MiB 748 MiB ± 12.1 MiB +2.57 %
arco-pro_development-mode + rss memory 567 MiB ± 20.5 MiB 577 MiB ± 25.7 MiB +1.68 %
arco-pro_development-mode_hmr + rss memory 638 MiB ± 59.9 MiB 656 MiB ± 79.2 MiB +2.90 %
arco-pro_production-mode + rss memory 728 MiB ± 42 MiB 731 MiB ± 20.6 MiB +0.35 %
arco-pro_production-mode_generate-package-json-webpack-plugin + rss memory 730 MiB ± 14.1 MiB 745 MiB ± 17 MiB +2.01 %
arco-pro_production-mode_persistent-cold + rss memory 863 MiB ± 51.8 MiB 848 MiB ± 44.5 MiB -1.71 %
arco-pro_production-mode_persistent-hot + rss memory 711 MiB ± 24.1 MiB 732 MiB ± 13.4 MiB +2.86 %
arco-pro_production-mode_traverse-chunk-modules + rss memory 727 MiB ± 14.4 MiB 746 MiB ± 19.2 MiB +2.65 %
large-dyn-imports_development-mode + rss memory 645 MiB ± 4.63 MiB 656 MiB ± 9.91 MiB +1.75 %
large-dyn-imports_production-mode + rss memory 528 MiB ± 6.7 MiB 544 MiB ± 5.39 MiB +3.12 %
threejs_development-mode_10x + rss memory 527 MiB ± 27.9 MiB 550 MiB ± 21.9 MiB +4.25 %
threejs_development-mode_10x_hmr + rss memory 1128 MiB ± 58.7 MiB 1124 MiB ± 160 MiB -0.36 %
threejs_production-mode_10x + rss memory 818 MiB ± 29.1 MiB 833 MiB ± 22.7 MiB +1.80 %
threejs_production-mode_10x_persistent-cold + rss memory 933 MiB ± 25.3 MiB 949 MiB ± 32.8 MiB +1.68 %
threejs_production-mode_10x_persistent-hot + rss memory 863 MiB ± 57.2 MiB 877 MiB ± 49.4 MiB +1.53 %

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented on 33654c7 Jan 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Ecosystem CI detail: Open

suite result
modernjs ❌ failure
rspress ✅ success
rslib ❌ failure
rsbuild ✅ success
rsdoctor ✅ success
examples ✅ success
devserver ✅ success
nuxt ✅ success

Please sign in to comment.