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!: rework import.meta.glob #7537

Merged
merged 43 commits into from
May 8, 2022
Merged

feat!: rework import.meta.glob #7537

merged 43 commits into from
May 8, 2022

Conversation

antfu
Copy link
Member

@antfu antfu commented Mar 31, 2022

Description

Port https://github.com/antfu/vite-plugin-glob to the core.

Rendered docs

Close #8032

TODO

  • Setup vite-plugin-glob
  • Fix HMR tests
  • Remove core logic for import.meta.glob handling
  • Migrate implementation of vite-plugin-glob to core.

Notes for Changelog


Breaking changes

  • Keys of import.meta.glob are now relative to the current module.
  • When using an alias with import.meta.glob, the keys are always absolute.
// file: /foo/index.js
const modules = import.meta.glob('../foo/*.js')

// transformed:
const modules = {
-  '../foo/bar.js': () => {}
+  './bar.js': () => {}
}

Features

Glob Import Rework

Based on the experiments we made in vite-plugin-glob, it's now part of the Vue 3 core with the enhancements:

  • Multiple globs patterns are allowed by passing an array as the first argument
  • Negative globs are supported for excluding the glob results.
  • import.meta.globEager are unified as import.meta.glob('pattern', { eager: true })
  • Named imports are supported, with tree shaking capability when used with eager: true.
  • Custom queries are supported.

Learn more at Glob Import

@antfu antfu changed the title feat: test vite-plugin-glob takeover feat: migrate vite-plugin-glob May 7, 2022
@antfu antfu changed the title feat: migrate vite-plugin-glob feat: port vite-plugin-glob May 7, 2022
@antfu antfu added the enhancement New feature or request label May 8, 2022
@antfu antfu added this to the 3.0 milestone May 8, 2022
docs/guide/features.md Outdated Show resolved Hide resolved
docs/guide/features.md Outdated Show resolved Hide resolved
docs/guide/features.md Outdated Show resolved Hide resolved
It's possible to only import parts of the modules with the `import` options.

```ts
const modules = import.meta.glob('./dir/*.js', { import: 'setup' })
Copy link
Member

Choose a reason for hiding this comment

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

Are multiple imports supported with an array? Should we add a section about this or maybe just use it in the example?

Suggested change
const modules = import.meta.glob('./dir/*.js', { import: 'setup' })
const modules = import.meta.glob('./dir/*.js', { import: ['setup', 'render'] })

Copy link
Member Author

@antfu antfu May 8, 2022

Choose a reason for hiding this comment

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

No, it does not support arrays. Referring to the eager: true example, the named import will be directly used as the value instead of the "Module" object. For multiple named imports they might better use multiple statements.

Copy link
Member

Choose a reason for hiding this comment

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

Gotcha. Sound good since most of the cases when using glob would require a single import, so looks good to me to wait until users request the feature. We could support both string or array if we need to go there anyway.

Co-authored-by: patak <matias.capeletto@gmail.com>
Comment on lines +401 to +405
```ts
const modules = import.meta.glob('./dir/*.js', {
query: { foo: 'bar', bar: true }
})
```
Copy link
Member

Choose a reason for hiding this comment

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

Just a note, it would be good to avoid the name query since the way we add metadata/modifiers to imports is probably going to change in the future. But overriding as to allow for multiple values doesn't sound future-proof, and any other more generic name may actually end up conflicting with whatever gets standardized in the end. I thought of metadata, modifiers, with... we still have time until v3 to bike shed a bit if we find a more generic name that we are sure will not collide later. But for the moment, I think we can move forward with query

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess unless we are going to break our convention of using queries in v3.0, maybe naming it as query is still the most intuitive way to do it. In the future, if we find an alternative that does not use queries, (if it's not v3, probably v4) we could break this to align. It might be hard for now to foresee what's the format we gonna use in the future.

}
scripts[key] = {
loader,
contents
Copy link
Member

Choose a reason for hiding this comment

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

This is the one place that I'm still unsure it won't affect us. It is strange to me that if a user has:

import 'module-a.js'
import 'module-b.js'

And modifies the code to

import.meta.glob('module-?.js', { eager: true })`

Then scanning would be affected.

Or is this already taken care of in the PR? 🤔
Would it be possible to run the glob plugin when import.plugin.glob is present before this analysis if not?

@patak-dev patak-dev merged commit 330e0a9 into main May 8, 2022
@patak-dev patak-dev deleted the chore/vite-plugin-glob branch May 8, 2022 08:16
@patak-dev
Copy link
Member

This is awesome 🚀

@patak-dev
Copy link
Member

Linking for reference a discussion to stabilize experimental.importGlobRestoreExtension

cc @brillout

@JessicaSachs
Copy link
Contributor

JessicaSachs commented Sep 7, 2023

The output that import.meta.glob gave me when I dist'd my library was a little rough! Is there any control over how the glob gets expanded? I just want access to the file path of each module found, (MAYBE) its content, and then to mutate the module that called import.meta.glob before it gets code split.

Yesterday I ended up writing my own Vite plugin yesterday to manually export and control the names and formats of the exports in my library entry file. My local plugin was highly inspired (read: copy pasted) from other plugins in our ecosystem that use the Vite server watcher + fast-glob to generate files.

Is there an easy way to do this that I missed? I dug through rollup + vite plugin docs and other plugins for like 6-10 straight hours yesterday

I was mainly looking at:

@patak-dev any thoughts?

@patak-dev
Copy link
Member

@JessicaSachs Anthony sent a PR to tackle a similar issue here:

That PR is a good place to continue the discussion. @antfu presented the PR yesterday in the last Vite team meeting, but it wasn't clear to the group if it should be included in core, or keep it as a plugin. Maybe it would be good to copy your comment there 👍🏼

@asineth0
Copy link

I am currently using import.meta.glob to import 1500+ PNGs (for emojis) in my app with { as: "url", eager: true } and it causes the dev server to make 1500+ requests for each image, which causes the dev server to become very slow. It would be nice if it didn't require an entire request just for a JS file that has a default export with the URL to the asset.

@citrus327
Copy link

Is there any change that import.meta.glob support lazy load?

I think it also solves #7537 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Port vite-plugin-glob to core for v3
5 participants