@@ -3,7 +3,13 @@ import MagicString from 'magic-string'
33import { stripLiteral } from 'strip-literal'
44import type { Plugin } from '../plugin'
55import type { ResolvedConfig } from '../config'
6- import { transformStableResult } from '../utils'
6+ import type { ResolveFn } from '../'
7+ import {
8+ isParentDirectory ,
9+ normalizePath ,
10+ slash ,
11+ transformStableResult
12+ } from '../utils'
713import { fileToUrl } from './asset'
814import { preloadHelperId } from './importAnalysisBuild'
915
@@ -18,6 +24,9 @@ import { preloadHelperId } from './importAnalysisBuild'
1824 * ```
1925 */
2026export function assetImportMetaUrlPlugin ( config : ResolvedConfig ) : Plugin {
27+ const normalizedPublicDir = normalizePath ( config . publicDir )
28+ let assetResolver : ResolveFn
29+
2130 return {
2231 name : 'vite:asset-import-meta-url' ,
2332 async transform ( code , id , options ) {
@@ -63,16 +72,45 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
6372 }
6473
6574 const url = rawUrl . slice ( 1 , - 1 )
66- const file = path . resolve ( path . dirname ( id ) , url )
67- // Get final asset URL. Catch error if the file does not exist,
68- // in which we can resort to the initial URL and let it resolve in runtime
69- const builtUrl = await fileToUrl ( file , config , this ) . catch ( ( ) => {
75+ let file : string | undefined
76+ if ( url . startsWith ( '.' ) ) {
77+ file = slash ( path . resolve ( path . dirname ( id ) , url ) )
78+ } else {
79+ assetResolver ??= config . createResolver ( {
80+ extensions : [ ] ,
81+ mainFields : [ ] ,
82+ tryIndex : false ,
83+ preferRelative : true
84+ } )
85+ file = await assetResolver ( url , id )
86+ file ??= url . startsWith ( '/' )
87+ ? slash ( path . join ( config . publicDir , url ) )
88+ : slash ( path . resolve ( path . dirname ( id ) , url ) )
89+ }
90+
91+ // Get final asset URL. If the file does not exist,
92+ // we fall back to the initial URL and let it resolve in runtime
93+ let builtUrl : string | undefined
94+ if ( file ) {
95+ try {
96+ if ( isParentDirectory ( normalizedPublicDir , file ) ) {
97+ const publicPath =
98+ '/' + path . posix . relative ( normalizedPublicDir , file )
99+ builtUrl = await fileToUrl ( publicPath , config , this )
100+ } else {
101+ builtUrl = await fileToUrl ( file , config , this )
102+ }
103+ } catch {
104+ // do nothing, we'll log a warning after this
105+ }
106+ }
107+ if ( ! builtUrl ) {
70108 const rawExp = code . slice ( index , index + exp . length )
71109 config . logger . warnOnce (
72110 `\n${ rawExp } doesn't exist at build time, it will remain unchanged to be resolved at runtime`
73111 )
74- return url
75- } )
112+ builtUrl = url
113+ }
76114 s . overwrite (
77115 index ,
78116 index + exp . length ,
0 commit comments