@@ -2,7 +2,7 @@ import fs from 'node:fs'
2
2
import path from 'node:path'
3
3
import colors from 'picocolors'
4
4
import type { PartialResolvedId } from 'rollup'
5
- import { exports } from 'resolve.exports'
5
+ import { exports , imports } from 'resolve.exports'
6
6
import { hasESMSyntax } from 'mlly'
7
7
import type { Plugin } from '../plugin'
8
8
import {
@@ -55,6 +55,7 @@ export const browserExternalId = '__vite-browser-external'
55
55
export const optionalPeerDepId = '__vite-optional-peer-dep'
56
56
57
57
const nodeModulesInPathRE = / (?: ^ | \/ ) n o d e _ m o d u l e s \/ /
58
+ const subpathImportsPrefix = '#'
58
59
59
60
const isDebug = process . env . DEBUG
60
61
const debug = createDebugger ( 'vite:resolve-details' , {
@@ -152,6 +153,29 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin {
152
153
scan : resolveOpts ?. scan ?? resolveOptions . scan ,
153
154
}
154
155
156
+ const resolveSubpathImports = ( id : string , importer ?: string ) => {
157
+ if ( ! importer || ! id . startsWith ( subpathImportsPrefix ) ) return
158
+ const basedir = path . dirname ( importer )
159
+ const pkgJsonPath = lookupFile ( basedir , [ 'package.json' ] , {
160
+ pathOnly : true ,
161
+ } )
162
+ if ( ! pkgJsonPath ) return
163
+
164
+ const pkgData = loadPackageData ( pkgJsonPath , options . preserveSymlinks )
165
+ return resolveExportsOrImports (
166
+ pkgData . data ,
167
+ id ,
168
+ options ,
169
+ targetWeb ,
170
+ 'imports' ,
171
+ )
172
+ }
173
+
174
+ const resolvedImports = resolveSubpathImports ( id , importer )
175
+ if ( resolvedImports ) {
176
+ id = resolvedImports
177
+ }
178
+
155
179
if ( importer ) {
156
180
const _importer = isWorkerRequest ( importer )
157
181
? splitFileAndPostfix ( importer ) . file
@@ -958,7 +982,13 @@ export function resolvePackageEntry(
958
982
// resolve exports field with highest priority
959
983
// using https://github.com/lukeed/resolve.exports
960
984
if ( data . exports ) {
961
- entryPoint = resolveExports ( data , '.' , options , targetWeb )
985
+ entryPoint = resolveExportsOrImports (
986
+ data ,
987
+ '.' ,
988
+ options ,
989
+ targetWeb ,
990
+ 'exports' ,
991
+ )
962
992
}
963
993
964
994
const resolvedFromExports = ! ! entryPoint
@@ -1076,11 +1106,12 @@ function packageEntryFailure(id: string, details?: string) {
1076
1106
1077
1107
const conditionalConditions = new Set ( [ 'production' , 'development' , 'module' ] )
1078
1108
1079
- function resolveExports (
1109
+ function resolveExportsOrImports (
1080
1110
pkg : PackageData [ 'data' ] ,
1081
1111
key : string ,
1082
1112
options : InternalResolveOptionsWithOverrideConditions ,
1083
1113
targetWeb : boolean ,
1114
+ type : 'imports' | 'exports' ,
1084
1115
) {
1085
1116
const overrideConditions = options . overrideConditions
1086
1117
? new Set ( options . overrideConditions )
@@ -1115,7 +1146,8 @@ function resolveExports(
1115
1146
conditions . push ( ...options . conditions )
1116
1147
}
1117
1148
1118
- const result = exports ( pkg , key , {
1149
+ const fn = type === 'imports' ? imports : exports
1150
+ const result = fn ( pkg , key , {
1119
1151
browser : targetWeb && ! conditions . includes ( 'node' ) ,
1120
1152
require : options . isRequire && ! conditions . includes ( 'import' ) ,
1121
1153
conditions,
@@ -1149,7 +1181,13 @@ function resolveDeepImport(
1149
1181
if ( isObject ( exportsField ) && ! Array . isArray ( exportsField ) ) {
1150
1182
// resolve without postfix (see #7098)
1151
1183
const { file, postfix } = splitFileAndPostfix ( relativeId )
1152
- const exportsId = resolveExports ( data , file , options , targetWeb )
1184
+ const exportsId = resolveExportsOrImports (
1185
+ data ,
1186
+ file ,
1187
+ options ,
1188
+ targetWeb ,
1189
+ 'exports' ,
1190
+ )
1153
1191
if ( exportsId !== undefined ) {
1154
1192
relativeId = exportsId + postfix
1155
1193
} else {
0 commit comments