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

Improve the transform and re-enable optimizeServerReact #70101

Merged
merged 5 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions crates/napi/src/minify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ impl Task for MinifyTask {
fn patch_opts(opts: &mut JsMinifyOptions) {
opts.compress = BoolOrDataConfig::from_obj(TerserCompressorOptions {
inline: Some(TerserInlineOption::Num(2)),
global_defs: [(
"process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE".into(),
"production".into(),
)]
.iter()
.cloned()
.collect(),
..Default::default()
});
opts.mangle = BoolOrDataConfig::from_obj(MangleOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,39 @@ fn effect_has_side_effect_deps(call: &CallExpr) -> bool {
false
}

fn wrap_expr_with_env_prod_condition(call: CallExpr) -> Expr {
// Wrap the call expression with the condition
// turn it into `process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE` && <call>.
// And `process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE`` will be treated as `false` in
// minification. In this way the expression and dependencies are still available in
// compilation during bundling, but will be removed in the final DEC.
Expr::Bin(BinExpr {
span: DUMMY_SP,
left: Box::new(Expr::Member(MemberExpr {
obj: (Box::new(Expr::Member(MemberExpr {
obj: (Box::new(Expr::Ident(Ident {
sym: "process".into(),
span: DUMMY_SP,
..Default::default()
}))),

prop: MemberProp::Ident(IdentName {
sym: "env".into(),
span: DUMMY_SP,
}),
span: DUMMY_SP,
}))),
prop: (MemberProp::Ident(IdentName {
sym: "__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE".into(),
span: DUMMY_SP,
})),
span: DUMMY_SP,
})),
op: op!("&&"),
right: Box::new(Expr::Call(call)),
})
}

impl Fold for OptimizeServerReact {
fn fold_module_items(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
let mut new_items = vec![];
Expand Down Expand Up @@ -101,26 +134,28 @@ impl Fold for OptimizeServerReact {
fn fold_expr(&mut self, expr: Expr) -> Expr {
if let Expr::Call(call) = &expr {
if let Callee::Expr(box Expr::Ident(f)) = &call.callee {
// Remove `useEffect` call
// Mark `useEffect` as DCE'able
if let Some(use_effect_ident) = &self.use_effect_ident {
if &f.to_id() == use_effect_ident && !effect_has_side_effect_deps(call) {
return Expr::Lit(Lit::Null(Null { span: DUMMY_SP }));
// return Expr::Lit(Lit::Null(Null { span: DUMMY_SP }));
return wrap_expr_with_env_prod_condition(call.clone());
}
}
// Remove `useLayoutEffect` call
// Mark `useLayoutEffect` as DCE'able
if let Some(use_layout_effect_ident) = &self.use_layout_effect_ident {
if &f.to_id() == use_layout_effect_ident && !effect_has_side_effect_deps(call) {
return Expr::Lit(Lit::Null(Null { span: DUMMY_SP }));
return wrap_expr_with_env_prod_condition(call.clone());
}
}
} else if let Some(react_ident) = &self.react_ident {
if let Callee::Expr(box Expr::Member(member)) = &call.callee {
if let box Expr::Ident(f) = &member.obj {
if &f.to_id() == react_ident {
if let MemberProp::Ident(i) = &member.prop {
// Remove `React.useEffect` and `React.useLayoutEffect` calls
// Mark `React.useEffect` and `React.useLayoutEffect` as DCE'able
// calls in production
if i.sym == "useEffect" || i.sym == "useLayoutEffect" {
return Expr::Lit(Lit::Null(Null { span: DUMMY_SP }));
return wrap_expr_with_env_prod_condition(call.clone());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { useEffect, useLayoutEffect, useMemo } from 'react';
import React from 'react';
export default function App() {
null;
null;
process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE && useEffect(()=>{
console.log('Hello World');
}, []);
process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE && useLayoutEffect(()=>{
function foo() {}
return ()=>{};
}, [
1,
2,
App
]);
useLayoutEffect(()=>{}, [
runSideEffect()
]);
Expand All @@ -15,7 +24,9 @@ export default function App() {
const a = useMemo(()=>{
return 1;
}, []);
null;
process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE && React.useEffect(()=>{
console.log('Hello World');
});
return <div>
<h1>Hello World</h1>
</div>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,26 @@ export default function FilterItemDropdown({ list }) {
()=>null
];
const ref = useRef(null);
null;
null;
process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE && useEffect(()=>{
const handleClickOutside = (event)=>{
if (ref.current && !ref.current.contains(event.target)) {
setOpenSelect(false);
}
};
window.addEventListener('click', handleClickOutside);
return ()=>window.removeEventListener('click', handleClickOutside);
}, []);
process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE && useEffect(()=>{
list.forEach((listItem)=>{
if ('path' in listItem && pathname === listItem.path || 'slug' in listItem && searchParams.get('sort') === listItem.slug) {
setActive(listItem.title);
}
});
}, [
pathname,
list,
searchParams
]);
return <div className="relative" ref={ref}>
<div onClick={()=>{
setOpenSelect(!openSelect);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ export default function App() {
useEffect(()=>{
console.log('Hello World');
}, []);
null;
process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE && useLayoutEffect(()=>{
function foo() {}
return ()=>{};
}, [
1,
2,
App
]);
const a = useMemo(()=>{
return 1;
}, []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const Component = ({ children, fallback })=>{
false,
()=>null
];
null;
process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE && useEffect(()=>setMounted(true), []);
if (!mounted) {
return fallback ?? /* @__PURE__ */ jsx(Fragment, {});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { useEffect, useLayoutEffect, useMemo } from 'react';
import * as React from 'react';
export default function App() {
null;
null;
process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE && useEffect(()=>{
console.log('Hello World');
}, []);
process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE && useLayoutEffect(()=>{
function foo() {}
return ()=>{};
}, [
1,
2,
App
]);
useLayoutEffect(()=>{}, [
runSideEffect()
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ export class MinifyPlugin {
},
}
: {}),
compress: true,
compress: {
global_defs: {
'process.env.__NEXT_PRIVATE_MINIMIZE_MARCO_FALSE': false,
},
},
mangle: true,
module: 'unknown',
output: {
Expand Down
2 changes: 1 addition & 1 deletion packages/next/src/server/config-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,7 @@ export const defaultConfig: NextConfig = {
),
webpackBuildWorker: undefined,
webpackMemoryOptimizations: false,
optimizeServerReact: false,
optimizeServerReact: true,
useEarlyImport: false,
staleTimes: {
dynamic: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ export default function Page() {

// calling action1 fails!!
useEffect(() => {
action1().then((obj) => {
console.log('action1 returned:', obj)
})
if (globalThis.DO_NOT_TREE_SHAKE) {
action1().then((obj) => {
console.log('action1 returned:', obj)
})
}
}, [])

Expand Down
Loading