@@ -3,7 +3,13 @@ import MagicString from 'magic-string'
3
3
import { stripLiteral } from 'strip-literal'
4
4
import type { Plugin } from '../plugin'
5
5
import 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'
7
13
import { fileToUrl } from './asset'
8
14
import { preloadHelperId } from './importAnalysisBuild'
9
15
@@ -18,6 +24,9 @@ import { preloadHelperId } from './importAnalysisBuild'
18
24
* ```
19
25
*/
20
26
export function assetImportMetaUrlPlugin ( config : ResolvedConfig ) : Plugin {
27
+ const normalizedPublicDir = normalizePath ( config . publicDir )
28
+ let assetResolver : ResolveFn
29
+
21
30
return {
22
31
name : 'vite:asset-import-meta-url' ,
23
32
async transform ( code , id , options ) {
@@ -63,16 +72,45 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
63
72
}
64
73
65
74
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 ) {
70
108
const rawExp = code . slice ( index , index + exp . length )
71
109
config . logger . warnOnce (
72
110
`\n${ rawExp } doesn't exist at build time, it will remain unchanged to be resolved at runtime`
73
111
)
74
- return url
75
- } )
112
+ builtUrl = url
113
+ }
76
114
s . overwrite (
77
115
index ,
78
116
index + exp . length ,
0 commit comments