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: support a vite
entry point (export condition / main field)
#15643
Conversation
Run & review this pull request in StackBlitz Codeflow. |
vite
entry point (export condition / main field)vite
entry point (export condition / main field)
@@ -0,0 +1,10 @@ | |||
import { expect, test } from 'vitest' |
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.
This playground tests normal resolve.alias
usage.
@@ -0,0 +1,38 @@ | |||
import { describe, expect, test } from 'vitest' |
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.
This playground tests main/exports vite
usage. There's many different patterns.
vite
entry point (export condition / main field)vite
entry point (export condition / main field)
I'm not a fan of introducing Vite-specific metadata to the I think |
so the I agree with @bluwy that we should not add a new top-level field to package.json. This feature will only be used by new projects/adopted, so if it is only supported via exports maps that should be fine. Resolving via top level package.json fields is basically a legacy option today, no need to add new fields to it. |
@bluwy Interesting suggestion, but I don't see how @dominikg The I'm cool with removing the top-level |
You can configure it like this: {
"name": "lib",
"main": "./src/index.js",
"publishConfig": {
"main": "./dist/index.js"
}
} Conditions are indeed the more reliable way to declare them, but I don't think it's best for a tool that pushes towards standards. Encouraging the |
Also not keen about adding on to the pile of custom conditions. The landscape there is messy already and instead of adding more ways we should focus on enabling projects to migrate towards clean esm and providing tooling on top of existing conditions to make it work. case in point: Webpack made the "module" condition a thing https://webpack.js.org/guides/package-exports/#conditions and appearantly wmr also made "esmodules". ugh. All this does is creating more fragmentation some sort of lock-in mechanism where either all bundlers are forced to support each others inventions or projects will be tied to the one they started on forever. If you are using exports conditions, regardless of vite or an existing one, you would have to ship the referenced files in published packages too, as you have no control over the conditions used on the consumers side. So for public packages i think publishConfig is the way to go. For local only packages i think the development or production condition can work. |
7a71420
to
5354cd4
Compare
Took a step back to reimplement this. I agree, And that's exactly what I did. With my previous attempt, we were able to determine which packages are local or not. So I expanded this to automatically resolve source files of local packages, with no configuration from the consumer! This actually worked really well in the playground. |
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.
Thanks for tackling this from a different perspective. Besides my comments/concerns below, additionally I think from our last meeting, we should only need improved documentation on setting up monorepos in Vite.
I don't think there's something Vite can do internally or automatically to make it just work without injecting Vite-specific APIs or heuristics, which we want to avoid. So I think it's best we only do the documentation part, which is also tracked at #10447
// We need to support array conditions like `["./*.js", "./*.mjs"]` | ||
// So loop through each result and find one that actually exists | ||
if (result.length > 1) { | ||
for (const entry of result) { | ||
if (fs.existsSync(path.join(pkg.dir, entry))) { | ||
return entry | ||
} | ||
} | ||
} |
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.
We currently intentionally don't support this as it's not following the spec. Node.js only specifies to use the next element if the specifier is invalid, not if it don't exist on the fs.
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.
Good to know, I can remove it.
// We do this check here, so that it only runs once per package, | ||
// and not for every file in the package! | ||
if (inWorkspace) { | ||
for (const srcName of ['src', 'sources']) { |
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 don't think Vite should be hardcoding these directories. The users should be free to arrange the output however they want.
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 agree. I originally started adding this behind a config setting, similar to file extensions, but pushed it off to get the POC working.
Let's wait and see what Evan's thoughts on this are. I was tasked in finding a way to make monorepo setups "just work" without extra configuration (this includes alias mapping). I think for the majority of consumers, the automatic sources will work just fine. For others, they can just disable it, something like: resolve: {
localSources: false
} We could even expand the config and give consumers more control. But I feel like this is getting away from the original goal. resolve: {
localSources: ['package-a', 'package-b'],
srcDirs: ['lib', 'app'],
} |
Closing this as the Vite team had discussed with Evan and this isn't the way we want to go for now. |
Description
After speaking with @yyx990803, we're looking for a way to better support local packages (via monorepo/workspaces) without a build step. The current suggestion is to set
resolve.alias
es, but what if we leaned on the package ecosystem more?This PR adds support for a
vite
condition for packageexports
, and avite
main field (when not using exports). Both patterns can point to a source file, instead of a built file. Thesevite
entry points will only be resolved for local packages, and not packages found innode_modules
.Furthermore, for backwards compatibility, I wrapped this in a
vitePackageEntryPoints
experiment for now.For more information, look at the docs in this PR.
Additional context
What is the purpose of this pull request?
Before submitting the PR, please make sure you do the following
fixes #123
).