From 15b1a19af2cfcdc26857eff2fe2d41de93bd85a3 Mon Sep 17 00:00:00 2001 From: SoonIter Date: Fri, 10 Jan 2025 15:10:01 +0800 Subject: [PATCH] chore: update --- Cargo.lock | 1 + crates/node_binding/binding.d.ts | 35 +--- .../src/raw_options/raw_module/mod.rs | 10 + crates/rspack_core/src/concatenated_module.rs | 2 + crates/rspack_core/src/options/module.rs | 4 + crates/rspack_plugin_asset/Cargo.toml | 25 +-- crates/rspack_plugin_asset/src/lib.rs | 176 +++++++++++++++++- .../src/plugin/mod.rs | 1 + .../src/plugin/module_concatenation_plugin.rs | 23 ++- .../src/modern_module_library_plugin.rs | 18 +- packages/rspack/etc/core.api.md | 2 + packages/rspack/src/config/adapter.ts | 4 +- packages/rspack/src/config/types.ts | 5 + 13 files changed, 249 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1062c86508a..7922bb7855d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4358,6 +4358,7 @@ name = "rspack_plugin_asset" version = "0.2.0" dependencies = [ "async-trait", + "cow-utils", "mime_guess", "rayon", "rspack_base64", diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 63dbb845231..b601b43b93c 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -1105,17 +1105,6 @@ export interface JsTap { stage: number } -export interface NodeFsStats { - isFile: boolean - isDirectory: boolean - isSymlink: boolean - atimeMs: number - mtimeMs: number - ctimeMs: number - birthtimeMs: number - size: number -} - export interface PathWithInfo { path: string info: JsAssetInfo @@ -1142,6 +1131,8 @@ export interface RawAssetGeneratorOptions { outputPath?: JsFilename publicPath?: "auto" | JsFilename dataUrl?: RawAssetGeneratorDataUrlOptions | ((source: Buffer, context: RawAssetGeneratorDataUrlFnCtx) => string) + experimentalLibReExport?: boolean + experimentalLibPreserveImport?: boolean } export interface RawAssetInlineGeneratorOptions { @@ -1166,6 +1157,8 @@ export interface RawAssetResourceGeneratorOptions { filename?: JsFilename outputPath?: JsFilename publicPath?: "auto" | JsFilename + experimentalLibPreserveImport?: boolean + experimentalLibReExport?: boolean } export interface RawBannerPluginOptions { @@ -2139,23 +2132,3 @@ export interface RegisterJsTaps { registerHtmlPluginBeforeEmitTaps: (stages: Array) => Array<{ function: ((arg: JsBeforeEmitData) => JsBeforeEmitData); stage: number; }> registerHtmlPluginAfterEmitTaps: (stages: Array) => Array<{ function: ((arg: JsAfterEmitData) => JsAfterEmitData); stage: number; }> } - -export interface ThreadsafeNodeFS { - writeFile: (name: string, content: Buffer) => Promise - removeFile: (name: string) => Promise - mkdir: (name: string) => Promise - mkdirp: (name: string) => Promise - removeDirAll: (name: string) => Promise - readDir: (name: string) => Promise - readFile: (name: string) => Promise - stat: (name: string) => Promise - lstat: (name: string) => Promise - open: (name: string, flags: string) => Promise - rename: (from: string, to: string) => Promise - close: (fd: number) => Promise - write: (fd: number, content: Buffer, position: number) => Promise - writeAll: (fd: number, content: Buffer) => Promise - read: (fd: number, length: number, position: number) => Promise - readUntil: (fd: number, code: number, position: number) => Promise - readToEnd: (fd: number, position: number) => Promise -} diff --git a/crates/rspack_binding_values/src/raw_options/raw_module/mod.rs b/crates/rspack_binding_values/src/raw_options/raw_module/mod.rs index 66f891feefa..8aab65ee085 100644 --- a/crates/rspack_binding_values/src/raw_options/raw_module/mod.rs +++ b/crates/rspack_binding_values/src/raw_options/raw_module/mod.rs @@ -541,6 +541,9 @@ pub struct RawAssetGeneratorOptions { ts_type = "RawAssetGeneratorDataUrlOptions | ((source: Buffer, context: RawAssetGeneratorDataUrlFnCtx) => string)" )] pub data_url: Option, + + pub experimental_lib_re_export: Option, + pub experimental_lib_preserve_import: Option, } impl From for AssetGeneratorOptions { @@ -553,6 +556,8 @@ impl From for AssetGeneratorOptions { data_url: value .data_url .map(|i| RawAssetGeneratorDataUrlWrapper(i).into()), + experimental_lib_re_export: value.experimental_lib_re_export, + experimental_lib_preserve_import: value.experimental_lib_preserve_import, } } } @@ -585,6 +590,9 @@ pub struct RawAssetResourceGeneratorOptions { pub output_path: Option, #[napi(ts_type = "\"auto\" | JsFilename")] pub public_path: Option, + + pub experimental_lib_preserve_import: Option, + pub experimental_lib_re_export: Option, } impl From for AssetResourceGeneratorOptions { @@ -594,6 +602,8 @@ impl From 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()), + experimental_lib_preserve_import: value.experimental_lib_preserve_import, + experimental_lib_re_export: value.experimental_lib_re_export, } } } diff --git a/crates/rspack_core/src/concatenated_module.rs b/crates/rspack_core/src/concatenated_module.rs index 4b87057d969..03c68577571 100644 --- a/crates/rspack_core/src/concatenated_module.rs +++ b/crates/rspack_core/src/concatenated_module.rs @@ -639,6 +639,7 @@ impl Module for ConcatenatedModule { }; let runtime = runtime.as_deref(); let context = compilation.options.context.clone(); + dbg!(&context); let (modules_with_info, module_to_info_map) = self.get_modules_with_info(&compilation.get_module_graph(), runtime); @@ -955,6 +956,7 @@ impl Module for ConcatenatedModule { continue; } let used_name = export_info.get_used_name(&module_graph, None, runtime); + dbg!(&used_name); let Some(used_name) = used_name else { unused_exports.insert(name); diff --git a/crates/rspack_core/src/options/module.rs b/crates/rspack_core/src/options/module.rs index 6ed1fd4bc9f..395efbc32e2 100644 --- a/crates/rspack_core/src/options/module.rs +++ b/crates/rspack_core/src/options/module.rs @@ -455,6 +455,8 @@ pub struct AssetResourceGeneratorOptions { pub filename: Option, pub output_path: Option, pub public_path: Option, + pub experimental_lib_re_export: Option, + pub experimental_lib_preserve_import: Option, } #[cacheable] @@ -465,6 +467,8 @@ pub struct AssetGeneratorOptions { pub output_path: Option, pub public_path: Option, pub data_url: Option, + pub experimental_lib_re_export: Option, + pub experimental_lib_preserve_import: Option, } pub struct AssetGeneratorDataUrlFnCtx<'a> { diff --git a/crates/rspack_plugin_asset/Cargo.toml b/crates/rspack_plugin_asset/Cargo.toml index a4a641a01cd..21147684c39 100644 --- a/crates/rspack_plugin_asset/Cargo.toml +++ b/crates/rspack_plugin_asset/Cargo.toml @@ -8,19 +8,20 @@ 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 } +cow-utils = { 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"] diff --git a/crates/rspack_plugin_asset/src/lib.rs b/crates/rspack_plugin_asset/src/lib.rs index 493b6310e20..2f66aceb39f 100644 --- a/crates/rspack_plugin_asset/src/lib.rs +++ b/crates/rspack_plugin_asset/src/lib.rs @@ -3,10 +3,12 @@ use std::{borrow::Cow, hash::Hasher, path::PathBuf}; use async_trait::async_trait; +use cow_utils::CowUtils; use rayon::prelude::*; use rspack_cacheable::{cacheable, cacheable_dyn}; use rspack_core::{ - rspack_sources::{BoxSource, RawBufferSource, RawStringSource, SourceExt}, + get_js_chunk_filename_template, + rspack_sources::{BoxSource, CachedSource, RawBufferSource, RawStringSource, SourceExt}, AssetGeneratorDataUrl, AssetGeneratorDataUrlFnCtx, AssetInfo, AssetParserDataUrl, BuildMetaDefaultObject, BuildMetaExportsType, ChunkGraph, ChunkUkey, CodeGenerationDataAssetInfo, CodeGenerationDataFilename, CodeGenerationDataUrl, Compilation, CompilationRenderManifest, @@ -20,6 +22,8 @@ use rspack_hash::{RspackHash, RspackHashDigest}; use rspack_hook::{plugin, plugin_hook}; use rspack_util::{ext::DynHash, identifier::make_paths_relative}; +pub const AUTO_PUBLIC_PATH_PLACEHOLDER: &str = "__RSPACK_PLUGIN_ASSET_AUTO_PUBLIC_PATH__"; + #[plugin] #[derive(Debug, Default)] pub struct AssetPlugin; @@ -299,6 +303,32 @@ impl AssetParserAndGenerator { let public_path = PublicPath::ensure_ends_with_slash(public_path); Ok((public_path, info)) } + + fn get_experimental_lib_options( + &self, + module_generator_options: Option<&GeneratorOptions>, + ) -> Result<(bool, bool)> { + let experimental_lib_preserve_import = module_generator_options + .and_then(|x| x.get_asset()) + .and_then(|x| x.experimental_lib_preserve_import) + .or_else(|| { + module_generator_options + .and_then(|x| x.get_asset_resource()) + .and_then(|x| x.experimental_lib_preserve_import) + }) + .unwrap_or(false); + let experimental_lib_re_export = module_generator_options + .and_then(|x| x.get_asset()) + .and_then(|x| x.experimental_lib_re_export) + .or_else(|| { + module_generator_options + .and_then(|x| x.get_asset_resource()) + .and_then(|x| x.experimental_lib_re_export) + }) + .unwrap_or(false); + + Ok((experimental_lib_preserve_import, experimental_lib_re_export)) + } } // Webpack's default parser.dataUrlCondition.maxSize @@ -434,7 +464,6 @@ impl ParserAndGenerator for AssetParserAndGenerator { let exported_content = if parsed_asset_config.is_inline() { let resource_data: &ResourceData = normal_module.resource_resolved_data(); let data_url = module_generator_options.and_then(|x| x.asset_data_url()); - let encoded_source: String; if let Some(custom_data_url) = @@ -524,6 +553,71 @@ impl ParserAndGenerator for AssetParserAndGenerator { } else { unreachable!() }; + + let (experimental_lib_preserve_import, experimental_lib_re_export) = + self.get_experimental_lib_options(module_generator_options)?; + + if experimental_lib_preserve_import || experimental_lib_re_export { + if let Some(ref mut scope) = generate_context.concatenation_scope { + let is_module = compilation.options.output.module; + if parsed_asset_config.is_resource() { + scope.register_namespace_export(NAMESPACE_OBJECT_EXPORT); + if experimental_lib_re_export { + if is_module { + return Ok( + RawStringSource::from(format!( + r#"import {NAMESPACE_OBJECT_EXPORT} from {exported_content}; + export default {NAMESPACE_OBJECT_EXPORT};"# + )) + .boxed(), + ); + } else { + return Ok( + RawStringSource::from(format!( + r#"module.exports = require({NAMESPACE_OBJECT_EXPORT});"# + )) + .boxed(), + ); + } + } else if experimental_lib_preserve_import { + scope.register_namespace_export(NAMESPACE_OBJECT_EXPORT); + + if is_module { + return Ok( + RawStringSource::from(format!( + r#"import {NAMESPACE_OBJECT_EXPORT} from {exported_content};"# + )) + .boxed(), + ); + } else { + let supports_const = compilation.options.output.environment.supports_const(); + let declaration_kind = if supports_const { "const" } else { "var" }; + + return Ok( + RawStringSource::from(format!( + r#"{declaration_kind} {NAMESPACE_OBJECT_EXPORT} = require({NAMESPACE_OBJECT_EXPORT});"# + )) + .boxed(), + ); + } + } + } else { + if experimental_lib_re_export { + if is_module { + return Ok( + RawStringSource::from(format!(r#"export default {exported_content};"#)).boxed(), + ); + } else { + return Ok( + RawStringSource::from(format!(r#"module.exports = {exported_content};"#)) + .boxed(), + ); + } + } + } + } + }; + if let Some(ref mut scope) = generate_context.concatenation_scope { scope.register_namespace_export(NAMESPACE_OBJECT_EXPORT); let supports_const = compilation.options.output.environment.supports_const(); @@ -619,7 +713,7 @@ async fn render_manifest( compilation: &Compilation, chunk_ukey: &ChunkUkey, manifest: &mut Vec, - _diagnostics: &mut Vec, + diagnostics: &mut Vec, ) -> Result<()> { let chunk = compilation.chunk_by_ukey.expect_get(chunk_ukey); let module_graph = compilation.get_module_graph(); @@ -648,6 +742,7 @@ async fn render_manifest( .get::() .expect("should have asset_info") .inner(); + RenderManifestEntry { source: source.clone(), filename: asset_filename.to_owned(), @@ -665,9 +760,78 @@ async fn render_manifest( .collect::>(); manifest.extend(assets); + + // let (source, more_diagnostics) = compilation + // .old_cache + // .chunk_render_occasion + // .use_cache(compilation, chunk, &SourceType::JavaScript, || async { + // let source = render_chunk(compilation, chunk_ukey).await?; + // Ok((CachedSource::new(source).boxed(), Vec::new())) + // }) + // .await?; + + // diagnostics.extend(more_diagnostics); + // manifest.push(RenderManifestEntry { + // source: source.boxed(), + // filename: output_path, + // has_filename: false, + // info: asset_info, + // auxiliary: false, + // }); + Ok(()) } +// pub async fn render_chunk(compilation: &Compilation, chunk_ukey: &ChunkUkey) -> Result { +// let chunk = compilation.chunk_by_ukey.expect_get(chunk_ukey); +// let module_graph = compilation.get_module_graph(); +// let chunk_graph = &compilation.chunk_graph; + +// let ordered_modules = +// chunk_graph.get_chunk_modules_by_source_type(chunk_ukey, SourceType::JavaScript, &module_graph); + +// let mut source = String::new(); +// for module in ordered_modules { +// let code_gen_result = compilation +// .code_generation_results +// .get(&module.identifier(), Some(chunk.runtime())); + +// let result = code_gen_result +// .get(&SourceType::JavaScript) +// .map(|source| source.source()); +// source += &result.unwrap_or_default(); +// } +// let filename_template = get_js_chunk_filename_template( +// chunk, +// &compilation.options.output, +// &compilation.chunk_group_by_ukey, +// ); + +// let mut asset_info = AssetInfo::default(); +// let output_path = compilation.get_path_with_info( +// &filename_template, +// PathData::default() +// .chunk_id_optional(chunk.id(&compilation.chunk_ids).map(|id| id.as_str())) +// .chunk_hash_optional(chunk.rendered_hash( +// &compilation.chunk_hashes_results, +// compilation.options.output.hash_digest_length, +// )) +// .chunk_name_optional(chunk.name_for_filename_template(&compilation.chunk_ids)) +// .content_hash_optional(chunk.rendered_content_hash_by_source_type( +// &compilation.chunk_hashes_results, +// &SourceType::Css, +// compilation.options.output.hash_digest_length, +// )) +// .runtime(chunk.runtime().as_str()), +// &mut asset_info, +// )?; + +// let undo_path = PublicPath::render_auto_public_path(compilation, &output_path); +// source.cow_replace(AUTO_PUBLIC_PATH_PLACEHOLDER, &undo_path); + +// Ok(RawStringSource::from(source).boxed()) +// } + #[async_trait] impl Plugin for AssetPlugin { fn name(&self) -> &'static str { @@ -703,6 +867,12 @@ impl Plugin for AssetPlugin { }), ); + // ctx + // .context + // .compilation_hooks + // .render_manifest + // .tap(render_manifest::new(self)); + ctx.context.register_parser_and_generator_builder( rspack_core::ModuleType::AssetInline, Box::new(|_, _| Box::new(AssetParserAndGenerator::with_inline())), diff --git a/crates/rspack_plugin_javascript/src/plugin/mod.rs b/crates/rspack_plugin_javascript/src/plugin/mod.rs index abaecb6503a..2d08e9e4a1e 100644 --- a/crates/rspack_plugin_javascript/src/plugin/mod.rs +++ b/crates/rspack_plugin_javascript/src/plugin/mod.rs @@ -1142,6 +1142,7 @@ impl JsPlugin { let (chunk_modules_source, chunk_init_fragments) = render_chunk_modules(compilation, chunk_ukey, &chunk_modules, all_strict)? .unwrap_or_else(|| (RawStringSource::from_static("{}").boxed(), Vec::new())); + let mut render_source = RenderSource { source: chunk_modules_source, }; diff --git a/crates/rspack_plugin_javascript/src/plugin/module_concatenation_plugin.rs b/crates/rspack_plugin_javascript/src/plugin/module_concatenation_plugin.rs index ceac4894f52..45651a133f6 100644 --- a/crates/rspack_plugin_javascript/src/plugin/module_concatenation_plugin.rs +++ b/crates/rspack_plugin_javascript/src/plugin/module_concatenation_plugin.rs @@ -555,6 +555,9 @@ impl ModuleConcatenationPlugin { let box_module = module_graph .module_by_identifier(&root_module_id) .expect("should have module"); + let root_module_source_types = box_module.source_types(); + let is_root_module_asset_module = root_module_source_types.contains(&SourceType::Asset); + let root_module_ctxt = RootModuleContext { id: root_module_id, readable_identifier: box_module @@ -677,8 +680,26 @@ impl ModuleConcatenationPlugin { // .module_identifier_to_module // .remove(&root_module_id); // compilation.chunk_graph.clear + if is_root_module_asset_module { + chunk_graph.replace_module(&root_module_id, &new_module.id()); + chunk_graph.add_module(root_module_id); + for chunk_ukey in chunk_graph.get_module_chunks(new_module.id()).clone() { + let module = module_graph + .module_by_identifier(&root_module_id) + .expect("should exist module"); - chunk_graph.replace_module(&root_module_id, &new_module.id()); + let source_types = chunk_graph.get_chunk_module_source_types(&chunk_ukey, module); + let new_source_types = source_types + .iter() + .filter(|source_type| !matches!(source_type, SourceType::JavaScript)) + .copied() + .collect(); + chunk_graph.set_chunk_modules_source_types(&chunk_ukey, root_module_id, new_source_types); + chunk_graph.connect_chunk_and_module(chunk_ukey, root_module_id); + } + } else { + chunk_graph.replace_module(&root_module_id, &new_module.id()); + } module_graph.move_module_connections(&root_module_id, &new_module.id(), |c, dep| { let other_module = if *c.module_identifier() == root_module_id { diff --git a/crates/rspack_plugin_library/src/modern_module_library_plugin.rs b/crates/rspack_plugin_library/src/modern_module_library_plugin.rs index 5f3aaa00bce..67037c15ef6 100644 --- a/crates/rspack_plugin_library/src/modern_module_library_plugin.rs +++ b/crates/rspack_plugin_library/src/modern_module_library_plugin.rs @@ -114,15 +114,15 @@ impl ModernModuleLibraryPlugin { for module_id in unconcatenated_module_ids.into_iter() { // skip the asset module when the entry is asset module - let module_graph = compilation.get_module_graph(); - let Some(module) = module_graph.module_by_identifier(module_id) else { - continue; - }; - let source_types = module.source_types(); - let is_asset_module = source_types.contains(&SourceType::Asset); - if is_asset_module { - continue; - } + // let module_graph = compilation.get_module_graph(); + // let Some(module) = module_graph.module_by_identifier(module_id) else { + // continue; + // }; + // let source_types = module.source_types(); + // let is_asset_module = source_types.contains(&SourceType::Asset); + // if is_asset_module { + // continue; + // } let chunk_runtime = compilation .chunk_graph diff --git a/packages/rspack/etc/core.api.md b/packages/rspack/etc/core.api.md index 7cd4d39066e..3d0cac335c9 100644 --- a/packages/rspack/etc/core.api.md +++ b/packages/rspack/etc/core.api.md @@ -203,6 +203,8 @@ export type AssetResourceGeneratorOptions = { filename?: Filename; outputPath?: AssetModuleOutputPath; publicPath?: PublicPath; + experimentalLibReExport?: boolean; + experimentalLibPreserveImport?: boolean; }; // @public (undocumented) diff --git a/packages/rspack/src/config/adapter.ts b/packages/rspack/src/config/adapter.ts index d62f23c663b..dccdc60e1fe 100644 --- a/packages/rspack/src/config/adapter.ts +++ b/packages/rspack/src/config/adapter.ts @@ -674,7 +674,9 @@ function getRawAssetResourceGeneratorOptions( emit: options.emit, filename: options.filename, outputPath: options.outputPath, - publicPath: options.publicPath + publicPath: options.publicPath, + experimentalLibReExport: options.experimentalLibReExport, + experimentalLibPreserveImport: options.experimentalLibPreserveImport }; } diff --git a/packages/rspack/src/config/types.ts b/packages/rspack/src/config/types.ts index 3c928c65e00..1445f5e1a82 100644 --- a/packages/rspack/src/config/types.ts +++ b/packages/rspack/src/config/types.ts @@ -1163,6 +1163,11 @@ export type AssetResourceGeneratorOptions = { /** This option determines the URL prefix of the referenced 'asset' or 'asset/resource'*/ publicPath?: PublicPath; + + /** */ + experimentalLibReExport?: boolean; + /** */ + experimentalLibPreserveImport?: boolean; }; /** Generator options for asset modules. */