Skip to content

Commit

Permalink
Merge branch 'canary' into nested-components-example-update
Browse files Browse the repository at this point in the history
  • Loading branch information
samcx authored Jul 24, 2024
2 parents e50d95c + af6aa78 commit 02e924e
Show file tree
Hide file tree
Showing 213 changed files with 488,609 additions and 321,933 deletions.
2 changes: 1 addition & 1 deletion .github/.react-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
19.0.0-rc-dfd30974ab-20240613
19.0.0-rc-6230622a1a-20240610
4 changes: 4 additions & 0 deletions crates/next-custom-transforms/src/chain_transforms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ pub struct TransformOptions {

#[serde(default)]
pub optimize_server_react: Option<crate::transforms::optimize_server_react::Config>,

#[serde(default)]
pub debug_function_name: bool,
}

pub fn custom_before_pass<'a, C>(
Expand Down Expand Up @@ -297,6 +300,7 @@ where
},
None => Either::Right(noop()),
},
Optional::new(crate::transforms::debug_fn_name::debug_fn_name(), opts.debug_function_name),
as_folder(crate::transforms::pure::pure_magic(comments)),
)
}
Expand Down
185 changes: 185 additions & 0 deletions crates/next-custom-transforms/src/transforms/debug_fn_name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
use std::fmt::Write;

use swc_core::{
atoms::Atom,
common::{util::take::Take, DUMMY_SP},
ecma::{
ast::{
CallExpr, Callee, ExportDefaultExpr, Expr, FnDecl, FnExpr, KeyValueProp, MemberProp,
ObjectLit, PropOrSpread, VarDeclarator,
},
utils::ExprFactory,
visit::{as_folder, Fold, VisitMut, VisitMutWith},
},
};

pub fn debug_fn_name() -> impl VisitMut + Fold {
as_folder(DebugFnName::default())
}

#[derive(Default)]
struct DebugFnName {
path: String,
in_target: bool,
in_var_target: bool,
in_default_export: bool,
}

impl VisitMut for DebugFnName {
fn visit_mut_call_expr(&mut self, n: &mut CallExpr) {
if self.in_var_target || (self.path.is_empty() && !self.in_default_export) {
n.visit_mut_children_with(self);
return;
}

if let Some(target) = is_target_callee(&n.callee) {
let old_in_target = self.in_target;
self.in_target = true;
let orig_len = self.path.len();
if !self.path.is_empty() {
self.path.push('.');
}
self.path.push_str(&target);

n.visit_mut_children_with(self);

self.path.truncate(orig_len);
self.in_target = old_in_target;
} else {
n.visit_mut_children_with(self);
}
}

fn visit_mut_export_default_expr(&mut self, n: &mut ExportDefaultExpr) {
let old_in_default_export = self.in_default_export;
self.in_default_export = true;

n.visit_mut_children_with(self);

self.in_default_export = old_in_default_export;
}

fn visit_mut_expr(&mut self, n: &mut Expr) {
n.visit_mut_children_with(self);

if self.in_target {
match n {
Expr::Arrow(..) | Expr::Fn(FnExpr { ident: None, .. }) => {
// useLayoutEffect(() => ...);
//
// becomes
//
//
// useLayoutEffect({'MyComponent.useLayoutEffect': () =>
// ...}['MyComponent.useLayoutEffect']);

let orig = n.take();
let key = Atom::from(&*self.path);

*n = Expr::Object(ObjectLit {
span: DUMMY_SP,
props: vec![PropOrSpread::Prop(Box::new(
swc_core::ecma::ast::Prop::KeyValue(KeyValueProp {
key: swc_core::ecma::ast::PropName::Str(key.clone().into()),
value: Box::new(orig),
}),
))],
})
.computed_member(key)
.into();
}

_ => {}
}
}
}

fn visit_mut_fn_decl(&mut self, n: &mut FnDecl) {
let orig_len = self.path.len();
if !self.path.is_empty() {
self.path.push('.');
}
self.path.push_str(n.ident.sym.as_str());

n.visit_mut_children_with(self);

self.path.truncate(orig_len);
}

fn visit_mut_var_declarator(&mut self, n: &mut VarDeclarator) {
if let Some(Expr::Call(call)) = n.init.as_deref() {
let name = is_target_callee(&call.callee).and_then(|target| {
let name = n.name.as_ident()?;

Some((name.sym.clone(), target))
});

if let Some((name, target)) = name {
let old_in_var_target = self.in_var_target;
self.in_var_target = true;

let old_in_target = self.in_target;
self.in_target = true;
let orig_len = self.path.len();
if !self.path.is_empty() {
self.path.push('.');
}
let _ = write!(self.path, "{target}({name})");

n.visit_mut_children_with(self);

self.path.truncate(orig_len);
self.in_target = old_in_target;
self.in_var_target = old_in_var_target;
return;
}
}

if let Some(Expr::Arrow(..) | Expr::Fn(FnExpr { ident: None, .. }) | Expr::Call(..)) =
n.init.as_deref()
{
let name = n.name.as_ident();

if let Some(name) = name {
let orig_len = self.path.len();
if !self.path.is_empty() {
self.path.push('.');
}
self.path.push_str(name.sym.as_str());

n.visit_mut_children_with(self);

self.path.truncate(orig_len);
return;
}
}

n.visit_mut_children_with(self);
}
}

fn is_target_callee(e: &Callee) -> Option<Atom> {
match e {
Callee::Expr(e) => match &**e {
Expr::Ident(i) => {
if i.sym.starts_with("use") {
Some(i.sym.clone())
} else {
None
}
}
Expr::Member(me) => match &me.prop {
MemberProp::Ident(i) => {
if i.sym.starts_with("use") {
Some(i.sym.clone())
} else {
None
}
}
_ => None,
},
_ => None,
},
_ => None,
}
}
1 change: 1 addition & 0 deletions crates/next-custom-transforms/src/transforms/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod amp_attributes;
pub mod cjs_finder;
pub mod cjs_optimizer;
pub mod debug_fn_name;
pub mod disallow_re_export_all_in_page;
pub mod dynamic;
pub mod fonts;
Expand Down
22 changes: 22 additions & 0 deletions crates/next-custom-transforms/tests/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{
use next_custom_transforms::transforms::{
amp_attributes::amp_attributes,
cjs_optimizer::cjs_optimizer,
debug_fn_name::debug_fn_name,
dynamic::{next_dynamic, NextDynamicMode},
fonts::{next_font_loaders, Config as FontLoaderConfig},
named_import_transform::named_import_transform,
Expand Down Expand Up @@ -630,3 +631,24 @@ fn next_transform_strip_page_exports_fixture_default(output: PathBuf) {

run_stip_page_exports_test(&input, &output, ExportFilter::StripDataExports);
}

#[fixture("tests/fixture/debug-fn-name/**/input.js")]
fn test_debug_name(input: PathBuf) {
let output = input.parent().unwrap().join("output.js");

test_fixture(
syntax(),
&|_| {
let top_level_mark = Mark::fresh(Mark::root());
let unresolved_mark = Mark::fresh(Mark::root());

chain!(
swc_core::ecma::transforms::base::resolver(unresolved_mark, top_level_mark, true),
debug_fn_name()
)
},
&input,
&output,
Default::default(),
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const Component = () => {
useLayoutEffect(() => {})
useEffect(() => {})
const onClick = useCallback(() => [])
const computed = useMemo(() => {})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const Component = ()=>{
useLayoutEffect({
"Component.useLayoutEffect": ()=>{}
}["Component.useLayoutEffect"]);
useEffect({
"Component.useEffect": ()=>{}
}["Component.useEffect"]);
const onClick = useCallback({
"Component.useCallback(onClick)": ()=>[]
}["Component.useCallback(onClick)"]);
const computed = useMemo({
"Component.useMemo(computed)": ()=>{}
}["Component.useMemo(computed)"]);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function useSomething() {
useLayoutEffect(() => {})
useEffect(() => {})
const onClick = useCallback(() => [])
const computed = useMemo(() => {})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
function useSomething() {
useLayoutEffect({
"useSomething.useLayoutEffect": ()=>{}
}["useSomething.useLayoutEffect"]);
useEffect({
"useSomething.useEffect": ()=>{}
}["useSomething.useEffect"]);
const onClick = useCallback({
"useSomething.useCallback(onClick)": ()=>[]
}["useSomething.useCallback(onClick)"]);
const computed = useMemo({
"useSomething.useMemo(computed)": ()=>{}
}["useSomething.useMemo(computed)"]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default () => {
useLayoutEffect(() => {})
useEffect(() => {})
const onClick = useCallback(() => [])
const computed = useMemo(() => {})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default (()=>{
useLayoutEffect({
"useLayoutEffect": ()=>{}
}["useLayoutEffect"]);
useEffect({
"useEffect": ()=>{}
}["useEffect"]);
const onClick = useCallback({
"useCallback(onClick)": ()=>[]
}["useCallback(onClick)"]);
const computed = useMemo({
"useMemo(computed)": ()=>{}
}["useMemo(computed)"]);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const Component = someHoC(() => {
useLayoutEffect(() => {})
useEffect(() => {})
const onClick = useCallback(() => [])
const computed = useMemo(() => {})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const Component = someHoC(()=>{
useLayoutEffect({
"Component.useLayoutEffect": ()=>{}
}["Component.useLayoutEffect"]);
useEffect({
"Component.useEffect": ()=>{}
}["Component.useEffect"]);
const onClick = useCallback({
"Component.useCallback(onClick)": ()=>[]
}["Component.useCallback(onClick)"]);
const computed = useMemo({
"Component.useMemo(computed)": ()=>{}
}["Component.useMemo(computed)"]);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
useMemo(() => {})
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
useMemo(()=>{});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function MyComponent() {
useLayoutEffect(() => {})
useEffect(() => {})
const onClick = useCallback(() => [])
const computed = useMemo(() => {})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
function MyComponent() {
useLayoutEffect({
"MyComponent.useLayoutEffect": ()=>{}
}["MyComponent.useLayoutEffect"]);
useEffect({
"MyComponent.useEffect": ()=>{}
}["MyComponent.useEffect"]);
const onClick = useCallback({
"MyComponent.useCallback(onClick)": ()=>[]
}["MyComponent.useCallback(onClick)"]);
const computed = useMemo({
"MyComponent.useMemo(computed)": ()=>{}
}["MyComponent.useMemo(computed)"]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
function C() {
function handleClick() {}
const onClick = useCallback(handleClick, [])
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
function C() {
function handleClick() {}
const onClick = useCallback(handleClick, []);
}
1 change: 1 addition & 0 deletions crates/next-custom-transforms/tests/full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ fn test(input: &Path, minify: bool) {
optimize_barrel_exports: None,
optimize_server_react: None,
prefer_esm: false,
debug_function_name: false,
};

let unresolved_mark = Mark::new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ In `app`, you should use the three new hooks imported from `next/navigation`: [`
- The new `useRouter` hook is imported from `next/navigation` and has different behavior to the `useRouter` hook in `pages` which is imported from `next/router`.
- The [`useRouter` hook imported from `next/router`](/docs/pages/api-reference/functions/use-router) is not supported in the `app` directory but can continue to be used in the `pages` directory.
- The new `useRouter` does not return the `pathname` string. Use the separate `usePathname` hook instead.
- The new `useRouter` does not return the `query` object. Use the separate `useSearchParams` hook instead.
- The new `useRouter` does not return the `query` object. Search parameters and dynamic route parameters are now separate. Use the `useSearchParams` and `useParams` hooks instead.
- You can use `useSearchParams` and `usePathname` together to listen to page changes. See the [Router Events](/docs/app/api-reference/functions/use-router#router-events) section for more details.
- These new hooks are only supported in Client Components. They cannot be used in Server Components.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Here are some example cache configurations for common CI providers:

## Vercel

Next.js caching is automatically configured for you. There's no action required on your part.
Next.js caching is automatically configured for you. There's no action required on your part. If you are using Turborepo on Vercel, [learn more here](https://vercel.com/docs/monorepos/turborepo).

## CircleCI

Expand Down
Loading

0 comments on commit 02e924e

Please sign in to comment.