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

feat(node, cloudflare): fill in api surface for node:perf_hooks #257

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

IgorMinar
Copy link
Collaborator

  • added missing APIs
  • created a hybrid polyfill for cloudflare
  • updated injectable config for globalThis.performance

Reference: #

- added missing APIs
- created a hybrid polyfill for cloudflare
- updated injectable config for globalThis.performance
src/presets/nodeless.ts Outdated Show resolved Hide resolved
@pi0 pi0 changed the title feat(node, cloudflare): fill in API surface for node:perf_hooks feat(node, cloudflare): fill in api surface for node:perf_hooks Jun 12, 2024
@IgorMinar
Copy link
Collaborator Author

@pi0 I believe this PR is good to go. PTAL

@pi0 pi0 mentioned this pull request Jun 18, 2024
"perf_hooks",
"PerformanceObserverEntryList",
],
PerformanceResourceTiming: ["perf_hooks", "PerformanceResourceTiming"],
Copy link
Member

@pi0 pi0 Jun 18, 2024

Choose a reason for hiding this comment

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

To be honest, I'm still not sure about this part. Initial injections in nodeless (global, process, and Buffer) are all Node.js specific global which were safe to inject globally. Performance API is a Web standard on the other hand. By adding this injections we are effectively overriding any native global implementation in user-code to unenv/node.

I think this should be an explicit opt-in. wrangler preset (#262) is a good candidate because i suppose you also require explicit (Node-compat) from users to enable this and then things make sense.

Copy link
Member

Choose a reason for hiding this comment

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

(i would suggest to revert this part and split to another PR to unblock)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Performance API is a Web standard on the other hand. By adding this injections we are effectively overriding any native global implementation in user-code to unenv/node.

You make a really good point, Pooya! It's funny how we sometimes get caught up in not seeing the obvious.

I think the right thing here is to move these injects into the cloudflare preset because workerd doesn't offer Performance* APIs.

I'm not yet convinced that we need a dedicated wrangler preset. I'm hoping we really don't have to do that.

Would you be ok with me updating the PR by moving these injects into preset/cloudflare?

Copy link
Member

@pi0 pi0 Jun 18, 2024

Choose a reason for hiding this comment

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

I want to use same cloudflare preset in Nitro builds as well and users would face similar implicit opt-in to Node.js variant of Performance* variants if we do this for them (inject Web vs Node version)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I see what you mean. The issue you are bringing up is that Node's Performance* API is not 100% compatible with Web's Performance* and if someone relies on globals we'd be making the choice for them, which might not be good. This is quite messy. How big is the difference between the two?

@jasnell as a node core contributor, have you seen this become a problem in the node community? how do people deal with these compat issues?

Copy link
Member

@pi0 pi0 Jun 18, 2024

Choose a reason for hiding this comment

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

Difference is:

  • In node impl, we always implement class and won't fall back to globalThis.* natives if available, in Web we do
  • Some classes only allow constructor via polyfills and not with natives and we need it internally between polyfills
  • Node.js classes have additional props

The first is solvable somehow but I'm more worried about the design decisions we hare making for unenv. For me unless explicitly we are adding "node.js" compatibility, we should strictly stick with Web standards spec. Only for wrangler usage that uses unenv as Node.js compatibility layer it clearly makes sense but for generic polyfill, it breaks the concept.

I am thinking to expose new API from unenv that we can have flags like nodeCompat to make difference behavior.


In the meantime, let's move these to cloudflare as you suggested (we can have web for nodeless + node for cloudflare that overrides nodeless) 👍🏼 this PR seems unnecessarily being blocked.

Copy link

Choose a reason for hiding this comment

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

we do have performance.now() and performance.timeOrigin in workers. The impl in Node.js definitely has a bunch of Node.js specific stuff. It hasn't been too much of a problem in the ecosystem but it definitely warrants caution.

@IgorMinar
Copy link
Collaborator Author

@pi0 I'll get back to this one within a few days. I still care, just busy with other things.

@pi0
Copy link
Member

pi0 commented Jun 28, 2024

No rush, thanks for the update @IgorMinar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants