@@ -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,28 @@ 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 importerPkgJson = lookupFile ( basedir , [ 'package.json' ] , {
160
+ predicate : ( content ) => ! ! JSON . parse ( content ) . name ,
161
+ } )
162
+ if ( ! importerPkgJson ) return
163
+
164
+ return resolveExportsOrImports (
165
+ JSON . parse ( importerPkgJson ) ,
166
+ id ,
167
+ options ,
168
+ targetWeb ,
169
+ 'imports' ,
170
+ )
171
+ }
172
+
173
+ const resolvedImports = resolveSubpathImports ( id , importer )
174
+ if ( resolvedImports ) {
175
+ id = resolvedImports
176
+ }
177
+
155
178
if ( importer ) {
156
179
const _importer = isWorkerRequest ( importer )
157
180
? splitFileAndPostfix ( importer ) . file
@@ -958,7 +981,13 @@ export function resolvePackageEntry(
958
981
// resolve exports field with highest priority
959
982
// using https://github.com/lukeed/resolve.exports
960
983
if ( data . exports ) {
961
- entryPoint = resolveExports ( data , '.' , options , targetWeb )
984
+ entryPoint = resolveExportsOrImports (
985
+ data ,
986
+ '.' ,
987
+ options ,
988
+ targetWeb ,
989
+ 'exports' ,
990
+ )
962
991
}
963
992
964
993
const resolvedFromExports = ! ! entryPoint
@@ -1076,11 +1105,12 @@ function packageEntryFailure(id: string, details?: string) {
1076
1105
1077
1106
const conditionalConditions = new Set ( [ 'production' , 'development' , 'module' ] )
1078
1107
1079
- function resolveExports (
1108
+ function resolveExportsOrImports (
1080
1109
pkg : PackageData [ 'data' ] ,
1081
1110
key : string ,
1082
1111
options : InternalResolveOptionsWithOverrideConditions ,
1083
1112
targetWeb : boolean ,
1113
+ type : 'imports' | 'exports' ,
1084
1114
) {
1085
1115
const overrideConditions = options . overrideConditions
1086
1116
? new Set ( options . overrideConditions )
@@ -1115,7 +1145,8 @@ function resolveExports(
1115
1145
conditions . push ( ...options . conditions )
1116
1146
}
1117
1147
1118
- const result = exports ( pkg , key , {
1148
+ const fn = type === 'imports' ? imports : exports
1149
+ const result = fn ( pkg , key , {
1119
1150
browser : targetWeb && ! conditions . includes ( 'node' ) ,
1120
1151
require : options . isRequire && ! conditions . includes ( 'import' ) ,
1121
1152
conditions,
@@ -1149,7 +1180,13 @@ function resolveDeepImport(
1149
1180
if ( isObject ( exportsField ) && ! Array . isArray ( exportsField ) ) {
1150
1181
// resolve without postfix (see #7098)
1151
1182
const { file, postfix } = splitFileAndPostfix ( relativeId )
1152
- const exportsId = resolveExports ( data , file , options , targetWeb )
1183
+ const exportsId = resolveExportsOrImports (
1184
+ data ,
1185
+ file ,
1186
+ options ,
1187
+ targetWeb ,
1188
+ 'exports' ,
1189
+ )
1153
1190
if ( exportsId !== undefined ) {
1154
1191
relativeId = exportsId + postfix
1155
1192
} else {
0 commit comments