@@ -16,6 +16,7 @@ const {
16
16
String,
17
17
StringPrototypeEndsWith,
18
18
StringPrototypeIndexOf,
19
+ StringPrototypeLastIndexOf,
19
20
StringPrototypeReplace,
20
21
StringPrototypeSlice,
21
22
StringPrototypeSplit,
@@ -59,6 +60,36 @@ const userConditions = getOptionValue('--conditions');
59
60
const DEFAULT_CONDITIONS = ObjectFreeze ( [ 'node' , 'import' , ...userConditions ] ) ;
60
61
const DEFAULT_CONDITIONS_SET = new SafeSet ( DEFAULT_CONDITIONS ) ;
61
62
63
+ const pendingDeprecation = getOptionValue ( '--pending-deprecation' ) ;
64
+ const emittedPackageWarnings = new SafeSet ( ) ;
65
+ function emitFolderMapDeprecation ( match , pjsonUrl , isExports , base ) {
66
+ const pjsonPath = fileURLToPath ( pjsonUrl ) ;
67
+ if ( ! pendingDeprecation ) {
68
+ const nodeModulesIndex = StringPrototypeLastIndexOf ( pjsonPath ,
69
+ '/node_modules/' ) ;
70
+ if ( nodeModulesIndex !== - 1 ) {
71
+ const afterNodeModulesPath = StringPrototypeSlice ( pjsonPath ,
72
+ nodeModulesIndex + 14 ,
73
+ - 13 ) ;
74
+ try {
75
+ const { packageSubpath } = parsePackageName ( afterNodeModulesPath ) ;
76
+ if ( packageSubpath === '.' )
77
+ return ;
78
+ } catch { }
79
+ }
80
+ }
81
+ if ( emittedPackageWarnings . has ( pjsonPath + '|' + match ) )
82
+ return ;
83
+ emittedPackageWarnings . add ( pjsonPath + '|' + match ) ;
84
+ process . emitWarning (
85
+ `Use of deprecated folder mapping "${ match } " in the ${ isExports ?
86
+ '"exports"' : '"imports"' } field module resolution of the package at ${
87
+ pjsonPath } ${ base ? ` imported from ${ fileURLToPath ( base ) } ` : '' } .\n` +
88
+ `Update this package.json to use a subpath pattern like "${ match } *".` ,
89
+ 'DeprecationWarning' ,
90
+ 'DEP0148'
91
+ ) ;
92
+ }
62
93
63
94
function getConditionsSet ( conditions ) {
64
95
if ( conditions !== undefined && conditions !== DEFAULT_CONDITIONS ) {
@@ -507,6 +538,8 @@ function packageExportsResolve(
507
538
conditions ) ;
508
539
if ( resolved === null || resolved === undefined )
509
540
throwExportsNotFound ( packageSubpath , packageJSONUrl , base ) ;
541
+ if ( ! pattern )
542
+ emitFolderMapDeprecation ( bestMatch , packageJSONUrl , true , base ) ;
510
543
return { resolved, exact : pattern } ;
511
544
}
512
545
@@ -556,8 +589,11 @@ function packageImportsResolve(name, base, conditions) {
556
589
const resolved = resolvePackageTarget (
557
590
packageJSONUrl , target , subpath , bestMatch , base , pattern , true ,
558
591
conditions ) ;
559
- if ( resolved !== null )
592
+ if ( resolved !== null ) {
593
+ if ( ! pattern )
594
+ emitFolderMapDeprecation ( bestMatch , packageJSONUrl , false , base ) ;
560
595
return { resolved, exact : pattern } ;
596
+ }
561
597
}
562
598
}
563
599
}
@@ -570,13 +606,7 @@ function getPackageType(url) {
570
606
return packageConfig . type ;
571
607
}
572
608
573
- /**
574
- * @param {string } specifier
575
- * @param {URL } base
576
- * @param {Set<string> } conditions
577
- * @returns {URL }
578
- */
579
- function packageResolve ( specifier , base , conditions ) {
609
+ function parsePackageName ( specifier , base ) {
580
610
let separatorIndex = StringPrototypeIndexOf ( specifier , '/' ) ;
581
611
let validPackageName = true ;
582
612
let isScoped = false ;
@@ -610,6 +640,19 @@ function packageResolve(specifier, base, conditions) {
610
640
const packageSubpath = '.' + ( separatorIndex === - 1 ? '' :
611
641
StringPrototypeSlice ( specifier , separatorIndex ) ) ;
612
642
643
+ return { packageName, packageSubpath, isScoped } ;
644
+ }
645
+
646
+ /**
647
+ * @param {string } specifier
648
+ * @param {URL } base
649
+ * @param {Set<string> } conditions
650
+ * @returns {URL }
651
+ */
652
+ function packageResolve ( specifier , base , conditions ) {
653
+ const { packageName, packageSubpath, isScoped } =
654
+ parsePackageName ( specifier , base ) ;
655
+
613
656
// ResolveSelf
614
657
const packageConfig = getPackageScopeConfig ( base ) ;
615
658
if ( packageConfig . exists ) {
0 commit comments