Rust library to generate static websites
1use rolldown::{Bundler, BundlerOptions, InputItem, RawMinifyOptions};
2use std::{
3 env, fs,
4 path::{Path, PathBuf},
5};
6
7type DynError = Box<dyn std::error::Error>;
8
9fn main() {
10 if let Err(e) = try_main() {
11 eprintln!("{}", e);
12 std::process::exit(-1);
13 }
14}
15
16fn try_main() -> Result<(), DynError> {
17 let task = env::args().nth(1);
18 match task.as_deref() {
19 Some("build-js") => build_js()?,
20 Some("build-cli-js") => build_cli_js()?,
21 Some("build-maudit-js") => build_maudit_js()?,
22 _ => print_help(),
23 }
24 Ok(())
25}
26
27fn print_help() {
28 println!("Usage: cargo xtask <task>");
29 println!();
30 println!("Available tasks:");
31 println!(" build-js Bundle JavaScript/TypeScript assets for all crates");
32 println!(" build-cli-js Bundle JavaScript/TypeScript assets for the CLI crate");
33 println!(" build-maudit-js Bundle JavaScript/TypeScript assets for the maudit crate");
34}
35
36fn build_js() -> Result<(), DynError> {
37 println!("Building JavaScript for all crates...");
38 build_cli_js()?;
39 build_maudit_js()?;
40 println!("All JavaScript builds completed successfully!");
41 Ok(())
42}
43
44fn build_cli_js() -> Result<(), DynError> {
45 let workspace_root = project_root();
46 let cli_crate = workspace_root.join("crates/maudit-cli");
47 let js_src_dir = cli_crate.join("js");
48 let js_dist_dir = js_src_dir.join("dist");
49
50 println!("Building JavaScript for maudit-cli...");
51
52 // Remove and recreate the dist directory to clean old builds
53 if js_dist_dir.exists() {
54 fs::remove_dir_all(&js_dist_dir)?;
55 }
56 fs::create_dir_all(&js_dist_dir)?;
57
58 // Configure Rolldown bundler input
59 let input_items = vec![InputItem {
60 name: Some("client".to_string()),
61 import: js_src_dir.join("client.ts").to_string_lossy().to_string(),
62 }];
63
64 let bundler_options = BundlerOptions {
65 input: Some(input_items),
66 dir: Some(js_dist_dir.to_string_lossy().to_string()),
67 format: Some(rolldown::OutputFormat::Esm),
68 platform: Some(rolldown::Platform::Browser),
69 minify: Some(RawMinifyOptions::Bool(true)),
70 ..Default::default()
71 };
72
73 // Create and run the bundler
74 let runtime = tokio::runtime::Runtime::new()?;
75
76 runtime.block_on(async {
77 let mut bundler = Bundler::new(bundler_options)
78 .map_err(|e| format!("Failed to create bundler: {:?}", e))?;
79
80 bundler
81 .write()
82 .await
83 .map_err(|e| format!("Failed to bundle JavaScript: {:?}", e))?;
84
85 println!(
86 "Successfully bundled JavaScript files to {}",
87 js_dist_dir.display()
88 );
89
90 Ok::<(), DynError>(())
91 })?;
92
93 Ok(())
94}
95
96fn build_maudit_js() -> Result<(), DynError> {
97 let workspace_root = project_root();
98 let maudit_crate = workspace_root.join("crates/maudit");
99 let js_src_dir = maudit_crate.join("js");
100 let js_dist_dir = js_src_dir.join("dist");
101
102 println!("Building JavaScript for maudit...");
103
104 // Remove and recreate the dist directory to clean old builds
105 if js_dist_dir.exists() {
106 fs::remove_dir_all(&js_dist_dir)?;
107 }
108 fs::create_dir_all(&js_dist_dir)?;
109
110 // Configure Rolldown bundler input
111 let input_items = vec![
112 InputItem {
113 name: Some("prefetch".to_string()),
114 import: js_src_dir.join("prefetch.ts").to_string_lossy().to_string(),
115 },
116 InputItem {
117 name: Some("hover".to_string()),
118 import: js_src_dir
119 .join("prefetch")
120 .join("hover.ts")
121 .to_string_lossy()
122 .to_string(),
123 },
124 ];
125
126 let bundler_options = BundlerOptions {
127 input: Some(input_items),
128 dir: Some(js_dist_dir.to_string_lossy().to_string()),
129 format: Some(rolldown::OutputFormat::Esm),
130 platform: Some(rolldown::Platform::Browser),
131 minify: Some(RawMinifyOptions::Bool(true)),
132 ..Default::default()
133 };
134
135 // Create and run the bundler
136 let runtime = tokio::runtime::Runtime::new()?;
137
138 runtime.block_on(async {
139 let mut bundler = Bundler::new(bundler_options)
140 .map_err(|e| format!("Failed to create bundler: {:?}", e))?;
141
142 bundler
143 .write()
144 .await
145 .map_err(|e| format!("Failed to bundle JavaScript: {:?}", e))?;
146
147 println!(
148 "Successfully bundled JavaScript files to {}",
149 js_dist_dir.display()
150 );
151
152 Ok::<(), DynError>(())
153 })?;
154
155 Ok(())
156}
157
158fn project_root() -> PathBuf {
159 Path::new(&env!("CARGO_MANIFEST_DIR"))
160 .ancestors()
161 .nth(1)
162 .unwrap()
163 .to_path_buf()
164}