@@ -36,14 +36,16 @@ const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
36
36
const experimentalNetworkImports =
37
37
getOptionValue ( '--experimental-network-imports' ) ;
38
38
const typeFlag = getOptionValue ( '--input-type' ) ;
39
- const { URL , pathToFileURL, fileURLToPath, isURL, toPathIfFileURL } = require ( 'internal/url' ) ;
39
+ const { URL , pathToFileURL, fileURLToPath, isURL } = require ( 'internal/url' ) ;
40
40
const { canParse : URLCanParse } = internalBinding ( 'url' ) ;
41
+ const { legacyMainResolve : URLLegacyMainResolve } = internalBinding ( 'fs' ) ;
41
42
const {
42
43
ERR_INPUT_TYPE_NOT_ALLOWED ,
43
44
ERR_INVALID_ARG_TYPE ,
44
45
ERR_INVALID_MODULE_SPECIFIER ,
45
46
ERR_INVALID_PACKAGE_CONFIG ,
46
47
ERR_INVALID_PACKAGE_TARGET ,
48
+ ERR_INVALID_URL ,
47
49
ERR_MANIFEST_DEPENDENCY_MISSING ,
48
50
ERR_MODULE_NOT_FOUND ,
49
51
ERR_PACKAGE_IMPORT_NOT_DEFINED ,
@@ -132,13 +134,58 @@ function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) {
132
134
133
135
const realpathCache = new SafeMap ( ) ;
134
136
135
- /**
136
- * @param {string | URL } url
137
- * @returns {boolean }
138
- */
139
- function fileExists ( url ) {
140
- return internalModuleStat ( toNamespacedPath ( toPathIfFileURL ( url ) ) ) === 0 ;
141
- }
137
+ const mainResolveExtensions = [
138
+ '' ,
139
+ '.js' ,
140
+ '.json' ,
141
+ '.node' ,
142
+ '/index.js' ,
143
+ '/index.json' ,
144
+ '/index.node' ,
145
+ './index.js' ,
146
+ './index.json' ,
147
+ './index.node' ,
148
+ ] ;
149
+
150
+ const mainResolveReturnType = {
151
+ kInvalidUrl : - 2 ,
152
+ kModuleNotFound : - 1 ,
153
+ // 0-6: when packageConfig.main is defined
154
+ kResolvedByMain : 0 ,
155
+ kResolvedByMainJs : 1 ,
156
+ kResolvedByMainJson : 2 ,
157
+ kResolvedByMainNode : 3 ,
158
+ kResolvedByMainIndexJs : 4 ,
159
+ kResolvedByMainIndexJson : 5 ,
160
+ kResolvedByMainIndexNode : 6 ,
161
+ // 7-9: when packageConfig.main is NOT defined,
162
+ // or when the previous case didn't found the file
163
+ kResolvedByPackageAndJs : 7 ,
164
+ kResolvedByPackageAndJson : 8 ,
165
+ kResolvedByPackageAndNode : 9 ,
166
+ /**
167
+ * Get the URL for the guess resolved by URLLegacyMainResolve
168
+ *
169
+ * @param {number } resolvedOption
170
+ * @param {string } baseUrl
171
+ * @param {URL } packageJSONUrl
172
+ * @returns {string }
173
+ */
174
+ getGuessByResolvedOption : function ( resolvedOption , baseUrl , packageJSONUrl ) {
175
+ return new URL ( baseUrl + mainResolveExtensions [ resolvedOption ] , packageJSONUrl ) ;
176
+ } ,
177
+ /**
178
+ * When resolved option is equal or less than 6, means we found a valid file
179
+ * with the prefix that came from packageConfig.main
180
+ *
181
+ * @param {number } resolvedOption
182
+ * @param {PackageConfig } packageConfig
183
+ * @returns {string }
184
+ */
185
+ getBaseUrlByResolvedOption : function ( resolvedOption , packageConfig ) {
186
+ return resolvedOption <= mainResolveReturnType . kResolvedByMainNode ? `./${ packageConfig . main } ` : '' ;
187
+ } ,
188
+ } ;
142
189
143
190
/**
144
191
* Legacy CommonJS main resolution:
@@ -153,44 +200,23 @@ function fileExists(url) {
153
200
* @returns {URL }
154
201
*/
155
202
function legacyMainResolve ( packageJSONUrl , packageConfig , base ) {
156
- let guess ;
157
- if ( packageConfig . main !== undefined ) {
158
- // Note: fs check redundances will be handled by Descriptor cache here.
159
- if ( fileExists ( guess = new URL ( `./${ packageConfig . main } ` ,
160
- packageJSONUrl ) ) ) {
161
- return guess ;
162
- } else if ( fileExists ( guess = new URL ( `./${ packageConfig . main } .js` ,
163
- packageJSONUrl ) ) ) ;
164
- else if ( fileExists ( guess = new URL ( `./${ packageConfig . main } .json` ,
165
- packageJSONUrl ) ) ) ;
166
- else if ( fileExists ( guess = new URL ( `./${ packageConfig . main } .node` ,
167
- packageJSONUrl ) ) ) ;
168
- else if ( fileExists ( guess = new URL ( `./${ packageConfig . main } /index.js` ,
169
- packageJSONUrl ) ) ) ;
170
- else if ( fileExists ( guess = new URL ( `./${ packageConfig . main } /index.json` ,
171
- packageJSONUrl ) ) ) ;
172
- else if ( fileExists ( guess = new URL ( `./${ packageConfig . main } /index.node` ,
173
- packageJSONUrl ) ) ) ;
174
- else guess = undefined ;
175
- if ( guess ) {
176
- emitLegacyIndexDeprecation ( guess , packageJSONUrl , base ,
177
- packageConfig . main ) ;
178
- return guess ;
203
+ const resolvedOption = URLLegacyMainResolve ( packageJSONUrl . href , packageConfig . main ) ;
204
+
205
+ if ( resolvedOption < mainResolveReturnType . kResolvedByMain ) {
206
+ if ( resolvedOption === mainResolveReturnType . kInvalidUrl ) {
207
+ throw new ERR_INVALID_URL ( packageConfig . main || './index.js' ) ;
208
+ } else {
209
+ throw new ERR_MODULE_NOT_FOUND (
210
+ fileURLToPath ( new URL ( '.' , packageJSONUrl ) ) , fileURLToPath ( base ) ) ;
179
211
}
180
- // Fallthrough.
181
- }
182
- if ( fileExists ( guess = new URL ( './index.js' , packageJSONUrl ) ) ) ;
183
- // So fs.
184
- else if ( fileExists ( guess = new URL ( './index.json' , packageJSONUrl ) ) ) ;
185
- else if ( fileExists ( guess = new URL ( './index.node' , packageJSONUrl ) ) ) ;
186
- else guess = undefined ;
187
- if ( guess ) {
188
- emitLegacyIndexDeprecation ( guess , packageJSONUrl , base , packageConfig . main ) ;
189
- return guess ;
190
212
}
191
- // Not found.
192
- throw new ERR_MODULE_NOT_FOUND (
193
- fileURLToPath ( new URL ( '.' , packageJSONUrl ) ) , fileURLToPath ( base ) ) ;
213
+
214
+ const baseUrl = mainResolveReturnType . getBaseUrlByResolvedOption ( resolvedOption , packageConfig ) ;
215
+ const guess = mainResolveReturnType . getGuessByResolvedOption ( resolvedOption , baseUrl , packageJSONUrl ) ;
216
+
217
+ emitLegacyIndexDeprecation ( guess , packageJSONUrl , base , packageConfig . main ) ;
218
+
219
+ return guess ;
194
220
}
195
221
196
222
const encodedSepRegEx = / % 2 F | % 5 C / i;
@@ -1078,6 +1104,7 @@ module.exports = {
1078
1104
packageExportsResolve,
1079
1105
packageImportsResolve,
1080
1106
throwIfInvalidParentURL,
1107
+ legacyMainResolve,
1081
1108
} ;
1082
1109
1083
1110
// cycle
0 commit comments