6
6
ObjectPrototypeHasOwnProperty,
7
7
PromisePrototypeThen,
8
8
PromiseResolve,
9
+ StringPrototypeSlice,
9
10
} = primordials ;
10
- const { extname } = require ( 'path' ) ;
11
+ const { basename , extname, relative } = require ( 'path' ) ;
11
12
const { getOptionValue } = require ( 'internal/options' ) ;
12
13
const { fetchModule } = require ( 'internal/modules/esm/fetch_module' ) ;
13
14
const {
@@ -20,7 +21,7 @@ const experimentalNetworkImports =
20
21
getOptionValue ( '--experimental-network-imports' ) ;
21
22
const experimentalSpecifierResolution =
22
23
getOptionValue ( '--experimental-specifier-resolution' ) ;
23
- const { getPackageType } = require ( 'internal/modules/esm/resolve' ) ;
24
+ const { getPackageType, getPackageScopeConfig } = require ( 'internal/modules/esm/resolve' ) ;
24
25
const { URL , fileURLToPath } = require ( 'internal/url' ) ;
25
26
const { ERR_UNKNOWN_FILE_EXTENSION } = require ( 'internal/errors' ) . codes ;
26
27
@@ -52,7 +53,8 @@ function getDataProtocolModuleFormat(parsed) {
52
53
* @returns {string }
53
54
*/
54
55
function getFileProtocolModuleFormat ( url , context , ignoreErrors ) {
55
- const ext = extname ( url . pathname ) ;
56
+ const filepath = fileURLToPath ( url ) ;
57
+ const ext = extname ( filepath ) ;
56
58
if ( ext === '.js' ) {
57
59
return getPackageType ( url ) === 'module' ? 'module' : 'commonjs' ;
58
60
}
@@ -63,7 +65,19 @@ function getFileProtocolModuleFormat(url, context, ignoreErrors) {
63
65
if ( experimentalSpecifierResolution !== 'node' ) {
64
66
// Explicit undefined return indicates load hook should rerun format check
65
67
if ( ignoreErrors ) return undefined ;
66
- throw new ERR_UNKNOWN_FILE_EXTENSION ( ext , fileURLToPath ( url ) ) ;
68
+ let suggestion = '' ;
69
+ if ( getPackageType ( url ) === 'module' && ext === '' ) {
70
+ const config = getPackageScopeConfig ( url ) ;
71
+ const fileBasename = basename ( filepath ) ;
72
+ const relativePath = StringPrototypeSlice ( relative ( config . pjsonPath , filepath ) , 1 ) ;
73
+ suggestion = 'Loading extensionless files is not supported inside of ' +
74
+ '"type":"module" package.json contexts. The package.json file ' +
75
+ `${ config . pjsonPath } caused this "type":"module" context. Try ` +
76
+ `changing ${ filepath } to have a file extension. Note the "bin" ` +
77
+ 'field of package.json can point to a file with an extension, for example ' +
78
+ `{"type":"module","bin":{"${ fileBasename } ":"${ relativePath } .js"}}` ;
79
+ }
80
+ throw new ERR_UNKNOWN_FILE_EXTENSION ( ext , filepath , suggestion ) ;
67
81
}
68
82
69
83
return getLegacyExtensionFormat ( ext ) ?? null ;
0 commit comments