-
Notifications
You must be signed in to change notification settings - Fork 142
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
Add new watches API #1763
Add new watches API #1763
Conversation
packages/core/src/virtual-content.ts
Outdated
let files = readdirSync(dir); | ||
return { | ||
src: `export default [ | ||
${files.map(f => `"${f}"`).join(',')} |
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 specific case could probably also be solved by using vite import.meta.glob('full/path/dir/*')
. would it sill not do auto reload in that case?
other cases could solve it by creating imports to files, vite also supports ?raw
which would allow to include any file that needs to be in a virtual file.
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.
or you could do both.
import.meta.glob('full/path/dir/*')
export default [
${files.map(f => `"${f}"`).join(',')}
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.
Yes, a lot of cases can be done with import.meta.glob, and this was just a toy example to motivate virtual files with dependencies. We should use import.meta.glob where possible.
I don't think our existing entrypoint logic is a good fit for import.meta.glob though, because it needs to account for app-js merging. If you try to do that with multiple globs you will include and evaluate shadowed modules that should not be there, and I don't think a single glob is expressive enough.
@@ -29,7 +50,10 @@ export function resolver(): Plugin { | |||
}, | |||
load(id) { | |||
if (id.startsWith(virtualPrefix)) { | |||
return virtualContent(id.slice(virtualPrefix.length), resolverLoader.resolver); | |||
let { src, watches } = virtualContent(id.slice(virtualPrefix.length), resolverLoader.resolver); | |||
virtualDeps.set(id, watches); |
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.
prefix here the src with import.meta.glob(...watches)
. and filter watches for the ones containing globs.
files should just work with addWatchFile.
like that you do not need the configureServer
code.
let { src, watches } = virtualContent(id.slice(virtualPrefix.length), resolverLoader.resolver);
for (w of watches) {
if (w.includes('*')) {
src = `import.meta.glob($'{w}')\n` + src;
} else {
this.addWatchFile(w);
}
}
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.
Our actual use cases need more sophisticated filtering than we can do with import.meta.glob. For example, we need a way to include "node_modules/some-addon/app/components/foo.js" but only if "./components/foo.js" doesn't exist. If we do that with globs you will always evaluate the addon copy, even when it should not evaluate.
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.
mport.meta.glob is not eager, but can be configured to be so with params, so it shouldn't evaluate. but not sure if thats enough for the use case you are looking for
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.
Right, in the case of entrypoints we need the eager: true
variant.
Edit: This started as a sketch and evolved to how we want it to look Along the way we discovered that vite incorectly implements rollups `addWatchFile` API because (1) it's supposed to accept directories and doesn't and (2) it's supposed to resolve relative paths relative to the current working directory, not the current request.
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.
Looks good to me 🎉
This is just a toy example to motivate a watch api for virtual content.Edit: this has been trimmed down to only include the API we wantAlong the way we discovered that vite incorectly implements rollups
addWatchFile
API because (1) it's supposed to accept directories and doesn't and (2) it's supposed to resolve relative paths relative to the current working directory, not the current request.This example also needs #1762