@@ -36,14 +36,16 @@ const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
3636const experimentalNetworkImports =
3737 getOptionValue ( '--experimental-network-imports' ) ;
3838const typeFlag = getOptionValue ( '--input-type' ) ;
39- const { URL , pathToFileURL, fileURLToPath, isURL, toPathIfFileURL } = require ( 'internal/url' ) ;
39+ const { URL , pathToFileURL, fileURLToPath, isURL } = require ( 'internal/url' ) ;
4040const { canParse : URLCanParse } = internalBinding ( 'url' ) ;
41+ const { legacyMainResolve : URLLegacyMainResolve } = internalBinding ( 'fs' ) ;
4142const {
4243 ERR_INPUT_TYPE_NOT_ALLOWED ,
4344 ERR_INVALID_ARG_TYPE ,
4445 ERR_INVALID_MODULE_SPECIFIER ,
4546 ERR_INVALID_PACKAGE_CONFIG ,
4647 ERR_INVALID_PACKAGE_TARGET ,
48+ ERR_INVALID_URL ,
4749 ERR_MANIFEST_DEPENDENCY_MISSING ,
4850 ERR_MODULE_NOT_FOUND ,
4951 ERR_PACKAGE_IMPORT_NOT_DEFINED ,
@@ -132,13 +134,58 @@ function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) {
132134
133135const realpathCache = new SafeMap ( ) ;
134136
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+ } ;
142189
143190/**
144191 * Legacy CommonJS main resolution:
@@ -153,44 +200,23 @@ function fileExists(url) {
153200 * @returns {URL }
154201 */
155202function 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 ) ) ;
179211 }
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 ;
190212 }
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 ;
194220}
195221
196222const encodedSepRegEx = / % 2 F | % 5 C / i;
@@ -1078,6 +1104,7 @@ module.exports = {
10781104 packageExportsResolve,
10791105 packageImportsResolve,
10801106 throwIfInvalidParentURL,
1107+ legacyMainResolve,
10811108} ;
10821109
10831110// cycle
0 commit comments