oxc_minifier/options.rs
1use oxc_compat::EngineTargets;
2use rustc_hash::FxHashSet;
3
4pub use oxc_ecmascript::side_effects::PropertyReadSideEffects;
5
6#[derive(Debug, Clone)]
7pub struct CompressOptions {
8 /// Engine targets for feature detection.
9 ///
10 /// Used to determine which ES features are supported by the target engines
11 /// and whether transformations can be applied.
12 ///
13 /// Default: empty (supports all features)
14 pub target: EngineTargets,
15
16 /// Remove `debugger;` statements.
17 ///
18 /// Default `true`
19 pub drop_debugger: bool,
20
21 /// Remove `console.*` statements.
22 ///
23 /// Default `false`
24 pub drop_console: bool,
25
26 /// Join consecutive var, let and const statements.
27 ///
28 /// Default `true`
29 pub join_vars: bool,
30
31 /// Join consecutive simple statements using the comma operator.
32 ///
33 /// `a; b` -> `a, b`
34 ///
35 /// Default `true`
36 pub sequences: bool,
37
38 /// Drop unreferenced functions and variables.
39 pub unused: CompressOptionsUnused,
40
41 /// Keep function / class names.
42 pub keep_names: CompressOptionsKeepNames,
43
44 /// Treeshake Options .
45 /// <https://rollupjs.org/configuration-options/#treeshake>
46 pub treeshake: TreeShakeOptions,
47
48 /// Set of label names to drop from the code.
49 ///
50 /// Labeled statements matching these names will be removed during minification.
51 ///
52 /// Default: empty (no labels dropped)
53 pub drop_labels: FxHashSet<String>,
54
55 /// Limit the maximum number of iterations for debugging purpose.
56 pub max_iterations: Option<u8>,
57}
58
59impl Default for CompressOptions {
60 fn default() -> Self {
61 Self::smallest()
62 }
63}
64
65impl CompressOptions {
66 pub fn smallest() -> Self {
67 Self {
68 target: EngineTargets::default(),
69 keep_names: CompressOptionsKeepNames::all_false(),
70 drop_debugger: true,
71 drop_console: false,
72 join_vars: true,
73 sequences: true,
74 unused: CompressOptionsUnused::Remove,
75 treeshake: TreeShakeOptions::default(),
76 drop_labels: FxHashSet::default(),
77 max_iterations: None,
78 }
79 }
80
81 pub fn safest() -> Self {
82 Self {
83 target: EngineTargets::default(),
84 keep_names: CompressOptionsKeepNames::all_true(),
85 drop_debugger: false,
86 drop_console: false,
87 join_vars: true,
88 sequences: true,
89 unused: CompressOptionsUnused::Keep,
90 treeshake: TreeShakeOptions::default(),
91 drop_labels: FxHashSet::default(),
92 max_iterations: None,
93 }
94 }
95
96 pub fn dce() -> Self {
97 Self {
98 target: EngineTargets::default(),
99 keep_names: CompressOptionsKeepNames::all_true(),
100 drop_debugger: false,
101 drop_console: false,
102 join_vars: false,
103 sequences: false,
104 unused: CompressOptionsUnused::Remove,
105 treeshake: TreeShakeOptions::default(),
106 drop_labels: FxHashSet::default(),
107 max_iterations: None,
108 }
109 }
110}
111
112#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
113pub enum CompressOptionsUnused {
114 #[default]
115 Remove,
116 KeepAssign,
117 Keep,
118}
119
120#[derive(Debug, Clone, Copy, Default)]
121pub struct CompressOptionsKeepNames {
122 /// Keep function names so that `Function.prototype.name` is preserved.
123 ///
124 /// This does not guarantee that the `undefined` name is preserved.
125 ///
126 /// Default `false`
127 pub function: bool,
128
129 /// Keep class names so that `Class.prototype.name` is preserved.
130 ///
131 /// This does not guarantee that the `undefined` name is preserved.
132 ///
133 /// Default `false`
134 pub class: bool,
135}
136
137impl CompressOptionsKeepNames {
138 pub fn all_false() -> Self {
139 Self { function: false, class: false }
140 }
141
142 pub fn all_true() -> Self {
143 Self { function: true, class: true }
144 }
145
146 pub fn function_only() -> Self {
147 Self { function: true, class: false }
148 }
149
150 pub fn class_only() -> Self {
151 Self { function: false, class: true }
152 }
153}
154
155#[derive(Debug, Clone)]
156pub struct TreeShakeOptions {
157 /// Whether to respect the pure annotations.
158 ///
159 /// Pure annotations are the comments that marks that a expression is pure.
160 /// For example, `/* @__PURE__ */`, `/* #__NO_SIDE_EFFECTS__ */`.
161 ///
162 /// <https://rollupjs.org/configuration-options/#treeshake-annotations>
163 ///
164 /// Default `true`
165 pub annotations: bool,
166
167 /// Whether to treat this function call as pure.
168 ///
169 /// This function is called for normal function calls, new calls, and
170 /// tagged template calls (`foo()`, `new Foo()`, ``foo`b` ``).
171 ///
172 /// <https://rollupjs.org/configuration-options/#treeshake-manualpurefunctions>
173 pub manual_pure_functions: Vec<String>,
174
175 /// Whether property read accesses have side effects.
176 ///
177 /// <https://rollupjs.org/configuration-options/#treeshake-propertyreadsideeffects>
178 ///
179 /// Default [PropertyReadSideEffects::All]
180 pub property_read_side_effects: PropertyReadSideEffects,
181
182 /// Whether accessing a global variable has side effects.
183 ///
184 /// Accessing a non-existing global variable will throw an error.
185 /// Global variable may be a getter that has side effects.
186 ///
187 /// <https://rollupjs.org/configuration-options/#treeshake-unknownglobalsideeffects>
188 ///
189 /// Default `true`
190 pub unknown_global_side_effects: bool,
191
192 /// Whether invalid import statements have side effects.
193 ///
194 /// Accessing a non-existing import name will throw an error.
195 /// Also import statements that cannot be resolved will throw an error.
196 ///
197 /// Default `false`
198 pub invalid_import_side_effects: bool,
199}
200
201impl Default for TreeShakeOptions {
202 fn default() -> Self {
203 Self {
204 annotations: true,
205 manual_pure_functions: vec![],
206 property_read_side_effects: PropertyReadSideEffects::default(),
207 unknown_global_side_effects: true,
208 invalid_import_side_effects: false,
209 }
210 }
211}