Skip to main content

Library/Fn/SWC/
Compile.rs

1//! SWC-compatible compilation module (using OXC backend)
2//!
3//! This module provides the same compilation functionality as the original
4//! SWC compiler but uses OXC for parsing and transformation.
5
6#[tracing::instrument(skip(options))]
7/// Compiles TypeScript files from input directory to output directory
8///
9/// # Arguments
10///
11/// * `options` - Compilation options including entry, pattern, config, output
12///   directory
13/// * `_parallel` - Whether to use parallel compilation (currently unused - runs
14///   sequentially)
15pub async fn Fn(options:crate::Struct::SWC::Option, _parallel:bool) -> anyhow::Result<()> {
16	tracing_subscriber::fmt::init();
17
18	// Use OXC compiler instead of SWC
19	let compiler = std::sync::Arc::new(crate::Fn::OXC::Compiler::Compiler::new(options.config.clone()));
20
21	// Get the input base path
22	let input_base = options.entry[0][0].clone();
23
24	let output_base = options.output.clone();
25
26	let pattern = options.pattern.clone();
27
28	println!("Starting compilation from {} to {}", input_base, output_base);
29
30	// Use walkdir to find all TypeScript files in the input directory
31	// Exclude .d.ts declaration files to match VSCode's build process
32	let ts_files:Vec<String> = walkdir::WalkDir::new(&input_base)
33		.follow_links(true)
34		.into_iter()
35		.filter_map(|e| {
36			let entry = e.ok()?;
37
38			let path = entry.path();
39
40			let path_str = path.to_string_lossy();
41
42			// Skip .d.ts declaration files (like VSCode's noDeclarationsFilter)
43			if path_str.ends_with(".d.ts") {
44				None
45			} else if path.is_file() && path_str.ends_with(&pattern) {
46				Some(path_str.to_string())
47			} else {
48				None
49			}
50		})
51		.collect();
52
53	println!("Found {} TypeScript files in {}", ts_files.len(), input_base);
54
55	// Process files sequentially to avoid OXC globals issues
56	let mut count = 0;
57
58	let mut error = 0;
59
60	for file_path in ts_files {
61		print!(".");
62
63		std::io::stdout().flush().unwrap();
64
65		match tokio::fs::read_to_string(&file_path).await {
66			Ok(input) => {
67				// Calculate relative path from input base
68				let input_path = std::path::Path::new(&file_path);
69
70				let base_path = std::path::Path::new(&input_base);
71
72				let relative_path = input_path.strip_prefix(base_path).unwrap_or(input_path);
73
74				// Create output path preserving directory structure
75				let output_path = std::path::Path::new(&output_base).join(relative_path).with_extension("js");
76
77				match compiler.compile_file_to(&file_path, input, &output_path, options.use_define_for_class_fields) {
78					Ok(output) => {
79						debug!("Compiled: {} -> {}", file_path, output);
80
81						count += 1;
82					},
83
84					Err(e) => {
85						error!("Compilation error for {}: {}", file_path, e);
86
87						error += 1;
88					},
89				}
90			},
91
92			Err(e) => {
93				error!("Failed to read file {}: {}", file_path, e);
94
95				error += 1;
96			},
97		}
98	}
99
100	println!();
101
102	let outlook = compiler.outlook.lock().unwrap();
103
104	info!(
105		"Compilation complete. Processed {} files in {:?}. {} successful, {} failed.",
106		outlook.count, outlook.elapsed, count, error
107	);
108
109	// Print summary
110	println!("\n=== Compilation Summary ===");
111
112	println!("Total files processed: {}", outlook.count);
113
114	println!("Successful: {}", count);
115
116	println!("Failed: {}", error);
117
118	println!("Time elapsed: {:?}\n", outlook.elapsed);
119
120	Ok(())
121}
122
123use std::io::Write;
124
125use tracing::{debug, error, info};