-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
feat: add the builtins environment resolve
#18584
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
Conversation
|
I personally think this is a good idea. |
isBuiltinresolve option isBuiltin
| if (environment.config.consumer === 'server' && isBuiltin(resolved)) { | ||
| if (environment.config.resolve.isBuiltin(resolved)) { | ||
| return | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this does not work. cloudflare:* will be processed by esbuild and IIRC esbuild does not externalize them automatically and then it throws Could not resolve "cloudflare:*" error. I guess it needs to be return { path: resolved, external: true }.
But I wonder if we should set external: true for anything that was externalized by rollup plugins or resolve.external instead of checking isBuiltin here.
|
I think I'm ok with this if it helps simplify managing builtins. I was thinking If we do land this, I'd however prefer the option to be an array of strings or regexes instead of a function. |
572b283 to
4b53f67
Compare
I've updated it 🙂 Having this as an array of strings/regexes does feel much more natural 😄 (example diff) |
resolve option isBuiltinbuiltins environment resolve
e507323 to
8c0bc0a
Compare
| } else if ( | ||
| currentEnvironmentOptions.consumer === 'client' && | ||
| isNodeLikeBuiltin(id) | ||
| ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| } else if ( | |
| currentEnvironmentOptions.consumer === 'client' && | |
| isNodeLikeBuiltin(id) | |
| ) { | |
| } else if ( | |
| currentEnvironmentOptions.consumer === 'server' && | |
| isNodeLikeBuiltin(id) | |
| ) { | |
| if ( | |
| options.noExternal === true && | |
| // if both noExternal and external are true, noExternal will take the higher priority and bundle it. | |
| // only if the id is explicitly listed in external, we will externalize it and skip this error. | |
| (options.external === true || !options.external.includes(id)) | |
| ) { | |
| let message = `Cannot bundle node built-in module "${id}"` | |
| if (importer) { | |
| message += ` imported from "${path.relative( | |
| process.cwd(), | |
| importer, | |
| )}"` | |
| } | |
| message += `. Consider disabling environments.${this.environment.name}.noExternal or remove the built-in dependency.` | |
| this.error(message) | |
| } | |
| } if ( | |
| currentEnvironmentOptions.consumer === 'client' && | |
| isNodeLikeBuiltin(id) | |
| ) { |
How about moving the "if options.enableBuiltinNoExternalCheck block" here from above and removing options.enableBuiltinNoExternalCheck && and setting builtin: [] by default for ssr.target: 'webworker'?
By setting builtin: [], I mean updating this line to (consumer === 'server' && !isSsrTargetWebworkerEnvironment.
https://github.com/vitejs/vite/pull/18584/files#diff-11e17761d4ecfee8f8fde15c6d79b7bc0260176396a30dfd8e6f6bbaf5af4745R888
This way if an environment sets builtin and have some node builtin modules not included in builtin, Vite will show a more friendly error (Cannot bundle built-in module) when noExternal is set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made the changes in regards to enableBuiltinNoExternalCheck that you suggested, it sounds sensible to me 🙂👍
|
I've been trying to think of potential tests to add here but it is a bit tricky 🤔 (since builtins are related to specific environments/runtimes, such as workerd, and I don't think that using a whole environment/runtime just for testing this would be worth it 😕) if anyone would have any idea that'd be great 🙏 😄 |
I think there's a following option:
But actually we already have |
|
@sapphi-red thanks a lot for the options for testing this! 🫶 I will try to play with those 🙏 Regarding the miniflare one, right now I would try to avoid using that as I feel that a more generic non-cloudflare specific test would be better, moreover I would not really want to introduce a "miniflare environment" that could confuse people looking at it and thinking that that's the proper way to run use cloudflare/miniflare with the environment API |
Co-authored-by: 翠 / green <[email protected]>
Co-authored-by: 翠 / green <[email protected]>
sapphi-red
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! Thank you 😄
patak-dev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry 6.1 took a bit more to start than we expected Dario!
No, problem! I'm happy to see the PR merged! 🫶 😄 |
<!-- Thank you for contributing! --> ### Description Ported changes from the following PRs: - vitejs/vite#18889 - vitejs/vite#19300 - vitejs/vite#18584, vitejs/vite#19312 and some minor changes. With this PR and #4270, the tests in Vite repo should now pass with native resolve plugin. <!-- Please insert your description here and provide especially info about the "what" this PR is solving --> --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
<!-- Thank you for contributing! --> ### Description Ported changes from the following PRs: - vitejs/vite#18889 - vitejs/vite#19300 - vitejs/vite#18584, vitejs/vite#19312 and some minor changes. With this PR and #4270, the tests in Vite repo should now pass with native resolve plugin. <!-- Please insert your description here and provide especially info about the "what" this PR is solving --> --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: 翠 / green <[email protected]>
Description
The issue this PR is addressing that the current
isBuiltinmethods seems to be hardcoded for node:vite/packages/vite/src/node/utils.ts
Lines 105 to 109 in ce0eec9
This doesn't fully seems right to me given the new environment API, since different environments can have different builtins.
For example Cloudflare's workerd runtime has the following builtins:
cloudflare:emailcloudflare:socketscloudflare:workersIt can also include the node builtins based on the user's configuration.
So I think that it would be nice if environment authors could declare what builtin modules their environment has.
One final note, without this option it is pretty easy to workaround the hardcoded node
isBuiltinmethod, in dev environments could implement theirfetchModuleto externalize all their builtins (example) and for build those could be marked as external (example). There are also a few other places where these might need to be set like inoptimizeDeps.exclude(example). So this option I'm proposing is probably something not absolutely necessary but just something to avoiding having to specify such modules all over the place (but there might also be other benefits in lettingisBuiltinknow how to distinguish environment specific builtins 🤷 ).