diff --git a/Cargo.lock b/Cargo.lock index c9a29317273..d288ca8ef89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3658,6 +3658,7 @@ dependencies = [ "swc_config", "swc_core", "swc_plugin_import", + "swc_typescript", "tokio", "url", ] diff --git a/Cargo.toml b/Cargo.toml index 78cfbc7ae7e..b78b8801271 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,6 +81,7 @@ swc_error_reporters = { version = "=1.0.0" } swc_html = { version = "=0.154.0" } swc_html_minifier = { version = "=0.151.0", default-features = false } swc_node_comments = { version = "=0.27.0" } +swc_typescript = { version = "=0.8.1" } rspack_dojang = { version = "0.1.9" } [workspace.metadata.release] diff --git a/crates/rspack_loader_swc/Cargo.toml b/crates/rspack_loader_swc/Cargo.toml index ab6471b74fd..36983c2331e 100644 --- a/crates/rspack_loader_swc/Cargo.toml +++ b/crates/rspack_loader_swc/Cargo.toml @@ -34,5 +34,6 @@ stacker = { workspace = true } swc_config = { workspace = true } swc_core = { workspace = true, features = ["base", "ecma_ast", "common"] } swc_plugin_import = { version = "0.1.5", path = "../swc_plugin_import" } +swc_typescript = { workspace = true } tokio = { workspace = true } url = "2.5.0" diff --git a/crates/rspack_loader_swc/src/compiler.rs b/crates/rspack_loader_swc/src/compiler.rs index a02f4d2497e..6d342187c6b 100644 --- a/crates/rspack_loader_swc/src/compiler.rs +++ b/crates/rspack_loader_swc/src/compiler.rs @@ -31,6 +31,7 @@ use swc_core::common::{ }; use swc_core::common::{BytePos, SourceFile}; use swc_core::ecma::ast::{EsVersion, Program}; +use swc_core::ecma::codegen::to_code_with_comments; use swc_core::ecma::parser::{ parse_file_as_module, parse_file_as_program, parse_file_as_script, Syntax, }; @@ -40,6 +41,7 @@ use swc_core::{ base::{config::Options, try_with_handler}, common::Globals, }; +use swc_typescript::fast_dts::FastDts; use url::Url; fn minify_file_comments( @@ -402,6 +404,16 @@ impl SwcCompiler { program } + pub fn transform_dts(&self, config: BuiltInput) -> Result { + // let mut checker = FastDts::new(); + let comments = config.comments.clone().unwrap(); + + let module = config.program.clone().expect_module(); + + let dts_code = to_code_with_comments(Some(&comments), &module); + Ok(dts_code) + } + pub fn input_source_map( &self, input_src_map: &InputSourceMap, diff --git a/crates/rspack_loader_swc/src/lib.rs b/crates/rspack_loader_swc/src/lib.rs index d796ee989a1..7c5e02f64e0 100644 --- a/crates/rspack_loader_swc/src/lib.rs +++ b/crates/rspack_loader_swc/src/lib.rs @@ -133,10 +133,31 @@ impl SwcLoader { let ast = c.into_js_ast(program); let TransformOutput { code, map } = ast::stringify(&ast, codegen_options)?; + let emit_dts = swc_options + .config + .jsc + .experimental + .emit_isolated_dts + .into_bool() + && swc_options + .config + .jsc + .syntax + .is_some_and(|x| x.typescript()); + + if emit_dts { + let dts_code = c.transform_dts(built).unwrap(); + loader_context + .parse_meta + .entry("swc-loader-dts-extract".into()) + .and_modify(|v| v.push_str(&dts_code)); + } + let map = map .map(|m| SourceMap::from_json(&m)) .transpose() .map_err(|e| error!(e.to_string()))?; + loader_context.emit_diagnostic(diagnostic); loader_context.finish_with((code, map)); Ok(())