Skip to main content

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