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

perf(resolve): default extensions review #12470

Closed
wants to merge 3 commits into from

Conversation

patak-dev
Copy link
Member

@patak-dev patak-dev commented Mar 17, 2023

Description

Edit: this is no longer a breaking change. I reduced the scope of the PR to only the order change.

This is a breaking change targeting Vite 5. Sending a PR to start a discussion.

Current default resolve extensions are:

.mjs .js .mts .ts .jsx .tsx .json

Projects using Vite and JSX (React or Solid) need to include the corresponding framework plugin. These plugins could inject .jsx and .tsx to extensions for their users. So we could reduce the number of default extensions to check from 7 to 5 for Vue, Svelte, and other frameworks that don't use these extensions.

The current order could also be reviewed. We could resolve first .ts instead of .js as it is probably more common when the extension is missing. Most projects using ESM modules are going to use "type": "module" and .js instead of .mjs.

This PR proposes a new default value for extensions:

.ts .js .mts .mjs .json

What is the purpose of this pull request?

  • Bug fix
  • New Feature
  • Documentation update
  • Other

@stackblitz
Copy link

stackblitz bot commented Mar 17, 2023

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@patak-dev patak-dev added breaking change performance Performance related enhancement labels Mar 17, 2023
@patak-dev patak-dev added this to the 5.0 milestone Mar 17, 2023
@bluwy
Copy link
Member

bluwy commented Mar 18, 2023

I think the .m variant is first because if you have .mjs and .js side-by-side, you probably mean .mjs to take precedence. But with that said, it doesn't looks like node resolve this way so maybe it's fine if we go that way.

I'm in favour of having .js extensions resolve first before .ts though. Every project will have .js first, but not all projects have .ts files.

Removing .jsx and .tsx is an interesting idea, I think it would be good to try that out, but it would be nice to measure how much this improves things too, since it wouldn't improve best-case perf, but only worst-case perf? (best-case being that ./component that will match .jsx, worst-case being that ./typo that doesn't match any files.)

@patak-dev
Copy link
Member Author

I think the .m variant is first because if you have .mjs and .js side-by-side, you probably mean .mjs to take precedence. But with that said, it doesn't looks like node resolve this way so maybe it's fine if we go that way.

Good point, is it even defined what happen in this case? If node picks one of the two first, we should do that too.

I'm in favour of having .js extensions resolve first before .ts though. Every project will have .js first, but not all projects have .ts files.

My thought was that it may be more common to avoid the extension for .ts files than for .js files, no? But I don't know how to back this up.

Removing .jsx and .tsx is an interesting idea, I think it would be good to try that out, but it would be nice to measure how much this improves things too, since it wouldn't improve best-case perf, but only worst-case perf? (best-case being that ./component that will match .jsx, worst-case being that ./typo that doesn't match any files.)

I'll check. I don't expect the diff being that big but it is still a lot of checks. If you see cases like #12471, we are first failing all these checks before testing the real path for aliased absolute paths. I think the diff may become smaller though if we keep optimizing other the resolve plugin.

Conceptually though, why are we treating .jsx and .tsx in a special way that affects performance for all frameworks?

@bluwy
Copy link
Member

bluwy commented Mar 18, 2023

Good point, is it even defined what happen in this case? If node picks one of the two first, we should do that too.

Node seems to completely ignore .mjs and .cjs, and only resolve .js. But thinking again, since this affects resolving in packages for prebundling, there's a good chance a file with .mjs and .js are side-by-side. I think we should pick .mjs still.

My thought was that it may be more common to avoid the extension for .ts files than for .js files, no? But I don't know how to back this up.

I think it's equally common :D I usually go JS-only and I omit extensions in a Vite project too.

Conceptually though, why are we treating .jsx and .tsx in a special way that affects performance for all frameworks?

I think it's because we handle .jsx and .tsx by default with esbuild, though it isn't really meaningful indeed without a framework.

@patak-dev patak-dev added p2-nice-to-have Not breaking anything but nice to have (priority) and removed breaking change labels Aug 14, 2023
@patak-dev
Copy link
Member Author

I reduced the scope of the PR to only the order change. If we would like to explore removing the default JSX, we should do it later on in a different change (I'm not sure we should though). Also reduced the reordering to leave js before ts as it was before as I don't have enough data to propose that swap.

@patak-dev
Copy link
Member Author

Closing the PR for now, I think that @bluwy has a point about .mjs should have more priority than .js. I'm failing to find a good reference for this, but anyways, I think we should be pushing for people to start using extensions as much as possible instead of having to deal with this complexity in Vite.

@patak-dev patak-dev closed this Oct 16, 2023
@patak-dev patak-dev deleted the perf/review-default-extensions branch March 22, 2024 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p2-nice-to-have Not breaking anything but nice to have (priority) performance Performance related enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants