Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(es/minifier): Make AST compressor respect toplevel #6775

Merged
merged 15 commits into from
Jan 11, 2023
5 changes: 4 additions & 1 deletion crates/swc_ecma_minifier/src/compress/optimize/inline.rs
Expand Up @@ -29,7 +29,7 @@ where
&mut self,
ident: &mut Ident,
init: &mut Expr,
should_preserve: bool,
mut should_preserve: bool,
can_drop: bool,
) {
trace_op!(
Expand Down Expand Up @@ -58,6 +58,7 @@ where
if !usage.var_initialized {
return;
}

if self.data.top.used_arguments && usage.declared_as_fn_param {
return;
}
Expand Down Expand Up @@ -95,6 +96,8 @@ where
let is_inline_enabled =
self.options.reduce_vars || self.options.collapse_vars || self.options.inline != 0;

should_preserve |= !self.options.top_level() && usage.is_top_level;

self.vars.inline_with_multi_replacer(init);

// We inline arrays partially if it's pure (all elements are literal), and not
Expand Down
5 changes: 5 additions & 0 deletions crates/swc_ecma_minifier/src/program_data.rs
Expand Up @@ -121,6 +121,9 @@ pub(crate) struct VarUsageInfo {

pub(crate) pure_fn: bool,

/// Is the variable declared in top level?
pub(crate) is_top_level: bool,

/// `infects_to`. This should be renamed, but it will be done with another
/// PR. (because it's hard to review)
infects: Vec<Access>,
Expand Down Expand Up @@ -168,6 +171,7 @@ impl Default for VarUsageInfo {
used_in_non_child_fn: Default::default(),
accessed_props: Default::default(),
used_recursively: Default::default(),
is_top_level: Default::default(),
}
}
}
Expand Down Expand Up @@ -346,6 +350,7 @@ impl Storage for ProgramData {
// }

let v = self.vars.entry(i.to_id()).or_default();
v.is_top_level |= ctx.is_top_level;

if has_init && (v.declared || v.var_initialized) {
#[cfg(feature = "debug")]
Expand Down
@@ -0,0 +1,4 @@
{
"defaults": true,
"toplevel": false
}
24 changes: 24 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/4386/1/input.js
@@ -0,0 +1,24 @@
var application;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll reduce this file

(() => {
var __webpack_require__ = {};
(() => {
__webpack_require__.d = (exports, definition) => {
};
})();
(() => {
__webpack_require__.o = (obj, prop) => { };
})();
(() => {
__webpack_require__.r = (exports) => {
};
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"bootstrap": () => (bootstrap)
});
function bootstrap() {
alert();
}
application = __webpack_exports__;
})();
12 changes: 12 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/4386/1/output.js
@@ -0,0 +1,12 @@
var application;
(()=>{
var __webpack_require__ = {};
__webpack_require__.d = (exports, definition)=>{}, __webpack_require__.o = (obj, prop)=>{}, __webpack_require__.r = (exports)=>{};
var __webpack_exports__ = {};
function bootstrap() {
alert();
}
__webpack_require__.r(__webpack_exports__), __webpack_require__.d(__webpack_exports__, {
bootstrap: ()=>bootstrap
}), application = __webpack_exports__;
})();
@@ -0,0 +1,4 @@
{
"defaults": true,
"toplevel": true
}
24 changes: 24 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/4386/2/input.js
@@ -0,0 +1,24 @@
var application;
(() => {
var __webpack_require__ = {};
(() => {
__webpack_require__.d = (exports, definition) => {
};
})();
(() => {
__webpack_require__.o = (obj, prop) => { };
})();
(() => {
__webpack_require__.r = (exports) => {
};
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"bootstrap": () => (bootstrap)
});
function bootstrap() {
alert();
}
application = __webpack_exports__;
})();
11 changes: 11 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/4386/2/output.js
@@ -0,0 +1,11 @@
(()=>{
var __webpack_require__ = {};
__webpack_require__.d = (exports, definition)=>{}, __webpack_require__.o = (obj, prop)=>{}, __webpack_require__.r = (exports)=>{};
var __webpack_exports__ = {};
function bootstrap() {
alert();
}
__webpack_require__.r(__webpack_exports__), __webpack_require__.d(__webpack_exports__, {
bootstrap: ()=>bootstrap
});
})();
@@ -0,0 +1,4 @@
{
"defaults": true,
"toplevel": true
}
@@ -1,2 +1,2 @@
var b;
x(b);
var b, a;
a = b, x(a);
Expand Up @@ -633,6 +633,14 @@ impl TreeShaker {
} else if !self.in_block_stmt {
return false;
}

// Abort if the variable is declared on top level scope.
let ix = self.data.graph_ix.get_index_of(&name);
if let Some(ix) = ix {
if self.data.entries.contains(&(ix as u32)) {
return false;
}
}
}

if self.config.top_retain.contains(&name.0) {
Expand Down
3 changes: 3 additions & 0 deletions crates/swc_ecma_usage_analyzer/src/analyzer/ctx.rs
Expand Up @@ -21,6 +21,7 @@ where
}

#[derive(Debug, Default, Clone, Copy)]
#[non_exhaustive]
pub struct Ctx {
/// See [crate::marks::Marks]
pub skip_standalone: bool,
Expand Down Expand Up @@ -60,6 +61,8 @@ pub struct Ctx {
pub inline_prevented: bool,

pub is_op_assign: bool,

pub is_top_level: bool,
}

pub(super) struct WithCtx<'a, S>
Expand Down
7 changes: 6 additions & 1 deletion crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs
Expand Up @@ -79,7 +79,10 @@ where
let mut child = UsageAnalyzer {
data: Default::default(),
marks: self.marks,
ctx: self.ctx,
ctx: Ctx {
is_top_level: false,
..self.ctx
},
scope: Default::default(),
used_recursively: self.used_recursively.clone(),
};
Expand Down Expand Up @@ -849,6 +852,7 @@ where
fn visit_module(&mut self, n: &Module) {
let ctx = Ctx {
skip_standalone: true,
is_top_level: true,
..self.ctx
};
n.visit_children_with(&mut *self.with_ctx(ctx))
Expand All @@ -857,6 +861,7 @@ where
fn visit_script(&mut self, n: &Script) {
let ctx = Ctx {
skip_standalone: true,
is_top_level: true,
..self.ctx
};
n.visit_children_with(&mut *self.with_ctx(ctx))
Expand Down