Skip to main content

Rest/Fn/Bundle/
config.rs

1//! Bundle configuration
2//!
3//! Configuration options for the bundler.
4
5use super::BundleMode;
6
7/// Configuration for the bundler
8#[derive(Debug, Clone)]
9pub struct BundleConfig {
10	/// Bundling mode
11	pub mode:BundleMode,
12	/// Output directory for bundled files
13	pub output_dir:String,
14	/// Output filename pattern (e.g., "{name}.js")
15	pub output_file:String,
16	/// Enable source map generation
17	pub source_map:bool,
18	/// Inline source map in the output
19	pub inline_source_map:bool,
20	/// Enable minification
21	pub minify:bool,
22	/// Enable tree-shaking
23	pub tree_shaking:bool,
24	/// Target environment (es2022, es2024, etc.)
25	pub target:String,
26	/// Module format (commonjs, esmodule, amd, umd)
27	pub format:String,
28	/// Whether to generate a declaration file
29	pub declarations:bool,
30	/// Whether to watch for changes
31	pub watch:bool,
32	/// External modules (not to be bundled)
33	pub externals:Vec<String>,
34	/// Additional entry points
35	pub entries:Vec<String>,
36	/// Whether to split chunks (for code splitting)
37	pub split_chunks:bool,
38}
39
40impl Default for BundleConfig {
41	fn default() -> Self {
42		Self {
43			mode:BundleMode::SingleFile,
44			output_dir:"out".to_string(),
45			output_file:"{name}.js".to_string(),
46			source_map:true,
47			inline_source_map:false,
48			minify:false,
49			tree_shaking:true,
50			target:"es2024".to_string(),
51			format:"esmodule".to_string(),
52			declarations:false,
53			watch:false,
54			externals:Vec::new(),
55			entries:Vec::new(),
56			split_chunks:false,
57		}
58	}
59}
60
61impl BundleConfig {
62	/// Create a new config for simple single-file compilation
63	pub fn single_file() -> Self { Self { mode:BundleMode::SingleFile, ..Default::default() } }
64
65	/// Create a new config for bundling
66	pub fn bundle() -> Self { Self { mode:BundleMode::Bundle, ..Default::default() } }
67
68	/// Create a new config for esbuild mode
69	pub fn esbuild() -> Self { Self { mode:BundleMode::Esbuild, ..Default::default() } }
70
71	/// Create a new config for watch mode
72	pub fn watch() -> Self { Self { mode:BundleMode::Watch, watch:true, ..Default::default() } }
73
74	/// Set the output directory
75	pub fn with_output_dir(mut self, dir:impl Into<String>) -> Self {
76		self.output_dir = dir.into();
77		self
78	}
79
80	/// Set the output file pattern
81	pub fn with_output_file(mut self, file:impl Into<String>) -> Self {
82		self.output_file = file.into();
83		self
84	}
85
86	/// Enable source maps
87	pub fn with_source_map(mut self, enabled:bool) -> Self {
88		self.source_map = enabled;
89		self
90	}
91
92	/// Enable minification
93	pub fn with_minify(mut self, enabled:bool) -> Self {
94		self.minify = enabled;
95		self
96	}
97
98	/// Enable tree-shaking
99	pub fn with_tree_shaking(mut self, enabled:bool) -> Self {
100		self.tree_shaking = enabled;
101		self
102	}
103
104	/// Set the target
105	pub fn with_target(mut self, target:impl Into<String>) -> Self {
106		self.target = target.into();
107		self
108	}
109
110	/// Set the format
111	pub fn with_format(mut self, format:impl Into<String>) -> Self {
112		self.format = format.into();
113		self
114	}
115
116	/// Add an external module
117	pub fn add_external(mut self, external:impl Into<String>) -> Self {
118		self.externals.push(external.into());
119		self
120	}
121
122	/// Add an entry point
123	pub fn add_entry(mut self, entry:impl Into<String>) -> Self {
124		self.entries.push(entry.into());
125		self
126	}
127
128	/// Check if this config requires bundling
129	pub fn requires_bundle(&self) -> bool { self.mode.requires_bundle() }
130}
131
132#[cfg(test)]
133mod tests {
134	use super::*;
135
136	#[test]
137	fn test_default_config() {
138		let config = BundleConfig::default();
139		assert_eq!(config.mode, BundleMode::SingleFile);
140		assert_eq!(config.target, "es2024");
141	}
142
143	#[test]
144	fn test_single_file_config() {
145		let config = BundleConfig::single_file();
146		assert_eq!(config.mode, BundleMode::SingleFile);
147		assert!(!config.source_map);
148	}
149
150	#[test]
151	fn test_bundle_config() {
152		let config = BundleConfig::bundle();
153		assert_eq!(config.mode, BundleMode::Bundle);
154		assert!(config.tree_shaking);
155	}
156
157	#[test]
158	fn test_builder_pattern() {
159		let config = BundleConfig::default()
160			.with_output_dir("dist")
161			.with_output_file("bundle.js")
162			.with_minify(true)
163			.add_external("react")
164			.add_entry("src/index.ts");
165
166		assert_eq!(config.output_dir, "dist");
167		assert_eq!(config.output_file, "bundle.js");
168		assert!(config.minify);
169		assert_eq!(config.externals.len(), 1);
170		assert_eq!(config.entries.len(), 1);
171	}
172}