vite icon indicating copy to clipboard operation
vite copied to clipboard

import.meta.url URLs incorrectly require `./`

Open 43081j opened this issue 10 months ago • 3 comments

Describe the bug

When using URL to resolve assets for things like workers, a relative path doesn't actually need to begin with ./

For example:

(new URL('bar/baz', 'https://example.com/foo')).pathname; // `/bar/baz`

(new URL('bar/baz', 'https://example.com/foo/')).pathname; // `/foo/bar/baz`

Inside vite, we currently assume all relative URLs begin with ./ here: https://github.com/vitejs/vite/blob/e2e11b15a6083777ee521e26a3f79c3859abd411/packages/vite/src/node/plugins/assetImportMetaUrl.ts#L118-L133

this results in foo/bar warning us (via this warning), but ./foo/bar working correctly.

we should probably be treating all URL urls which are not absolute as relative (since that is what URL itself is doing).

though i see you have a bunch of astro-specific logic in there currently and im not sure how such a change would affect that.

Reproduction

https://github.com/vueuse/playground.vueuse.org/

Steps to reproduce

Build the vueuse playground without this patch.

You'll see a warning without the patch, and no warning with it.

System Info

N/A

Used Package Manager

npm

Logs

No response

Validations

43081j avatar Apr 09 '25 17:04 43081j

this isn't as simple as i thought, it seems.

nuxt currently aliases assets/* to your assets directory here: https://github.com/nuxt/nuxt/blob/b0b1bb6fc18237c9ac2cdcd72a1261643584fbc1/packages/schema/src/config/common.ts#L512

without nuxt, things work, so this change would actually just be an optimisation (avoiding visiting the resolver by directly loading relative files).

however, this points out that relative URLs are currently eaten up by the resolve plugin.

if we load assets/foo.js from /node_modules/package/index.js, we clearly mean to load /node_modules/package/assets/foo.js, but the alias plugin will currently apply and override this.

so you could argue that the alias plugin should ignore node_modules paths.

but then what is the expected behaviour in other directories? if i load assets/foo.js from /src/components, what is the intent? URL behaviour suggests we should be loading /src/components/assets/foo.js, but import behaviour suggests we should use the alias plugin and load /assets/foo.js.

i feel like someone in the wild must be relying on being able to use these aliases in URL though. so maybe the best we can do is ignore node_modules

edit: nuxt/ui depends on the nuxt aliases existing, and of course lives in node_modules. so we can't ignore node_modules 🤷

43081j avatar Apr 09 '25 17:04 43081j

Real-world reproduction (sort of minimal):

WORKING: Vite with @vue/repl Repo - passing build action

FAILING: Nuxt (+vite) with @vue/repl: Repo - failing build action

Log

[warn] 
new URL("assets/editor.worker-KaUq7_iC.js", import.meta.url) doesn't exist at build time, it will remain unchanged to be resolved at runtime. If this is intended, you can use the /* @vite-ignore */ comment to suppress this warning.
[warn] 
new URL("assets/vue.worker-C169KAy9.js", import.meta.url) doesn't exist at build time, it will remain unchanged to be resolved at runtime. If this is intended, you can use the /* @vite-ignore */ comment to suppress this warning.

OrbisK avatar Apr 09 '25 18:04 OrbisK

@43081j I think this is actually a "nuxt issue". Looks like nuxt has a resolve alias on "assets": https://github.com/nuxt/nuxt/blob/76b300eddae6d755948239c305bfcc587dd74197/packages/kit/test/load-nuxt-config.spec.ts#L21

Not sure if this is an issue. Maybe the build js should have ./ to prevent this 🤔

OrbisK avatar May 13 '25 16:05 OrbisK