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

Scope hoisting breaks React component names #8724

Open
bvaughn opened this issue Dec 28, 2022 · 9 comments
Open

Scope hoisting breaks React component names #8724

bvaughn opened this issue Dec 28, 2022 · 9 comments
Labels
💬 RFC Request For Comments Stale Ignore This issue is exempt from getting flagged as stale and autoremoved

Comments

@bvaughn
Copy link

bvaughn commented Dec 28, 2022

Given source code like so:

export default function Foo({ bar }: { bar: string }) {
  return <div>{bar}</div>;
}

Parcel output looks like this:

var $b2QPe$reactjsxruntime = require("react/jsx-runtime");
var $b2QPe$react = require("react");

function $parcel$export(e, n, v, s) {
  Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
}

$parcel$export(module.exports, "Foo", () => $6d390b7f2e6b107f);

function $6d390b7f2e6b107f({ bar }) {
  // ...
}

This kind of "breaks" developer experience for anything that consumes these components, because they won't appear in React DevTools when you search for them by name.

The only way (that I know of) to work around this is to add a displayName attribute:

export default function Foo({ bar }: { bar: string }) {
  return <div>{bar}</div>;
}

Foo.displayName = "Foo";

Unfortunately this breaks the generated TypeScript types:

declare declare namespace Foo {
    var displayName: string;
}

I think the only way to work around this is to case the component function before assigning a display name:

export default function Foo({ bar }: { bar: string }) {
  return <div>{bar}</div>;
}

(Foo as any).displayName = "PanelResizeHandle";

This isn't very intuitive though.

@devongovett
Copy link
Member

Related: #6092

@mischnic
Copy link
Member

mischnic commented Dec 28, 2022

Not doing is a rather big change and not possible without rewriting the packager plugin.
What would you expect Parcel to do regarding automatic insertion of displayName? Should these statements also be there in production builds of webapps when using your library?

@bvaughn
Copy link
Author

bvaughn commented Dec 28, 2022

What would you expect Parcel to do regarding automatic insertion of displayName?

I’m not sure I would expect Parcel to do anything out of the box for displayName since that’s a React convention. Having an easier way to opt-in could be nice though.

Should these statements also be there if you do a production build using your library?

Production builds matter less because those are generally mangled again as part of the application build process. Mangling function names for libraries (in dev mode) is a pretty big developer experience hit for React developers though, since it wipes out library component names in the React DevTools extension.

@mischnic
Copy link
Member

What I was trying to say was: Parcel could pretty easily create these $6d390b7f2e6b107f.displayName = "Foo"; statements.

But then the problem is (once you've published a library containing these lines) that they will also be included in every production build of webapps using your library.

And I'm not sure if if(process.env.NODE_ENV==="development") $6d390b7f2e6b107f.displayName = "Foo"; is a good idea (to improve that last point).

@bvaughn
Copy link
Author

bvaughn commented Dec 28, 2022

Yeah, I understood. I still think this is too React-centric to be a default behavior for Parcel:

I’m not sure I would expect Parcel to do anything out of the box for displayName since that’s a React convention.

@bvaughn
Copy link
Author

bvaughn commented Dec 28, 2022

To be clear, the thing I’m reporting is that the current situation is a bad downstream developer experience for React libraries without an obvious workaround.

Maybe even just documenting the workaround would be sufficient?

@bvaughn
Copy link
Author

bvaughn commented Dec 28, 2022

May be worth summarizing my concern:

As someone writing React library code to publish with Parcel, I can't do this because it will result in a bad downstream developer experience:

export default function Foo({ bar }: { bar: string }) {
  return <div>{bar}</div>;
}

And I can't do this:

export default function Foo({ bar }: { bar: string }) {
  return <div>{bar}</div>;
}

if (process.env.NODE_ENV==="development") {
  Foo.displayName = "Foo";
}

Because setting the displayName breaks TypeScript types and the NODE_ENV conditional will be stripped during parcel build.

So what I end up having to do is this:

(Foo as any).displayName = "PanelResizeHandle";

This works but leaves a displayName value in the user's final production code. It's not that bad since this type of string should compress well, but it's not great.

@mischnic mischnic added the 💬 RFC Request For Comments label Jan 1, 2023
@github-actions github-actions bot added the Stale Inactive issues label Jul 1, 2023
@bvaughn
Copy link
Author

bvaughn commented Jul 1, 2023

Boo.

@github-actions github-actions bot removed the Stale Inactive issues label Jul 1, 2023
@github-actions github-actions bot added the Stale Inactive issues label Dec 28, 2023
@bvaughn
Copy link
Author

bvaughn commented Dec 28, 2023

Bump

@github-actions github-actions bot removed the Stale Inactive issues label Dec 28, 2023
@github-actions github-actions bot added the Stale Inactive issues label Jun 26, 2024
@devongovett devongovett removed the Stale Inactive issues label Jun 26, 2024
@parcel-bundler parcel-bundler deleted a comment from github-actions bot Jun 28, 2024
@mischnic mischnic added the Stale Ignore This issue is exempt from getting flagged as stale and autoremoved label Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💬 RFC Request For Comments Stale Ignore This issue is exempt from getting flagged as stale and autoremoved
Projects
None yet
Development

No branches or pull requests

3 participants