33const internalFS = require ( 'internal/fs/utils' ) ;
44const { NativeModule } = require ( 'internal/bootstrap/loaders' ) ;
55const { extname } = require ( 'path' ) ;
6- const { realpathSync, readFileSync } = require ( 'fs' ) ;
6+ const { realpathSync } = require ( 'fs' ) ;
77const { getOptionValue } = require ( 'internal/options' ) ;
8+
89const preserveSymlinks = getOptionValue ( '--preserve-symlinks' ) ;
910const preserveSymlinksMain = getOptionValue ( '--preserve-symlinks-main' ) ;
10- const { ERR_INVALID_PACKAGE_CONFIG ,
11- ERR_TYPE_MISMATCH ,
12- ERR_UNKNOWN_FILE_EXTENSION } = require ( 'internal/errors' ) . codes ;
1311const experimentalJsonModules = getOptionValue ( '--experimental-json-modules' ) ;
14- const { resolve : moduleWrapResolve } = internalBinding ( 'module_wrap' ) ;
15- const { pathToFileURL, fileURLToPath, URL } = require ( 'internal/url' ) ;
12+
13+ const { resolve : moduleWrapResolve ,
14+ getPackageType } = internalBinding ( 'module_wrap' ) ;
15+ const { pathToFileURL, fileURLToPath } = require ( 'internal/url' ) ;
1616const asyncESM = require ( 'internal/process/esm_loader' ) ;
17+ const { ERR_TYPE_MISMATCH ,
18+ ERR_UNKNOWN_FILE_EXTENSION } = require ( 'internal/errors' ) . codes ;
1719
1820const realpathCache = new Map ( ) ;
19- // TOOD(@guybedford): Shared cache with C++
20- const pjsonCache = new Map ( ) ;
21+
22+ // const TYPE_NONE = 0;
23+ const TYPE_COMMONJS = 1 ;
24+ const TYPE_MODULE = 2 ;
2125
2226const extensionFormatMap = {
2327 '__proto__' : null ,
@@ -45,75 +49,6 @@ if (experimentalJsonModules) {
4549 } ) ;
4650}
4751
48- function readPackageConfig ( path , parentURL ) {
49- const existing = pjsonCache . get ( path ) ;
50- if ( existing !== undefined )
51- return existing ;
52- try {
53- return JSON . parse ( readFileSync ( path ) . toString ( ) ) ;
54- } catch ( e ) {
55- if ( e . code === 'ENOENT' ) {
56- pjsonCache . set ( path , null ) ;
57- return null ;
58- } else if ( e instanceof SyntaxError ) {
59- throw new ERR_INVALID_PACKAGE_CONFIG ( path , fileURLToPath ( parentURL ) ) ;
60- }
61- throw e ;
62- }
63- }
64-
65- function getPackageBoundaryConfig ( url , parentURL ) {
66- let pjsonURL = new URL ( 'package.json' , url ) ;
67- while ( true ) {
68- const pcfg = readPackageConfig ( fileURLToPath ( pjsonURL ) , parentURL ) ;
69- if ( pcfg )
70- return pcfg ;
71-
72- const lastPjsonURL = pjsonURL ;
73- pjsonURL = new URL ( '../package.json' , pjsonURL ) ;
74-
75- // Terminates at root where ../package.json equals ../../package.json
76- // (can't just check "/package.json" for Windows support).
77- if ( pjsonURL . pathname === lastPjsonURL . pathname )
78- return ;
79- }
80- }
81-
82- function getModuleFormat ( url , isMain , parentURL ) {
83- const pcfg = getPackageBoundaryConfig ( url , parentURL ) ;
84-
85- const legacy = ! pcfg || pcfg . type !== 'module' ;
86-
87- const ext = extname ( url . pathname ) ;
88-
89- let format = ( legacy ? legacyExtensionFormatMap : extensionFormatMap ) [ ext ] ;
90-
91- if ( ! format ) {
92- if ( isMain )
93- format = legacy ? 'commonjs' : 'module' ;
94- else
95- throw new ERR_UNKNOWN_FILE_EXTENSION ( fileURLToPath ( url ) ,
96- fileURLToPath ( parentURL ) ) ;
97- }
98-
99- // Check for mismatch between --type and file extension,
100- // and between --type and the "type" field in package.json.
101- if ( isMain && format !== 'module' && asyncESM . typeFlag === 'module' ) {
102- // Conflict between package scope type and --type
103- if ( ext === '.js' ) {
104- if ( pcfg && pcfg . type )
105- throw new ERR_TYPE_MISMATCH (
106- fileURLToPath ( url ) , ext , asyncESM . typeFlag , 'scope' ) ;
107- // Conflict between explicit extension (.mjs, .cjs) and --type
108- } else {
109- throw new ERR_TYPE_MISMATCH (
110- fileURLToPath ( url ) , ext , asyncESM . typeFlag , 'extension' ) ;
111- }
112- }
113-
114- return format ;
115- }
116-
11752function resolve ( specifier , parentURL ) {
11853 if ( NativeModule . canBeRequiredByUsers ( specifier ) ) {
11954 return {
@@ -138,8 +73,39 @@ function resolve(specifier, parentURL) {
13873 url . hash = old . hash ;
13974 }
14075
141- const format = getModuleFormat ( url , isMain , parentURL ) ;
76+ const type = getPackageType ( url . href ) ;
77+
78+ const ext = extname ( url . pathname ) ;
79+ const extMap =
80+ type !== TYPE_MODULE ? legacyExtensionFormatMap : extensionFormatMap ;
81+ let format = extMap [ ext ] ;
14282
83+ if ( isMain && asyncESM . typeFlag ) {
84+ // Conflict between explicit extension (.mjs, .cjs) and --type
85+ if ( ext === '.cjs' && asyncESM . typeFlag === 'module' ||
86+ ext === '.mjs' && asyncESM . typeFlag === 'commonjs' ) {
87+ throw new ERR_TYPE_MISMATCH (
88+ fileURLToPath ( url ) , ext , asyncESM . typeFlag , 'extension' ) ;
89+ }
90+
91+ // Conflict between package scope type and --type
92+ if ( ext === '.js' ) {
93+ if ( type === TYPE_MODULE && asyncESM . typeFlag === 'commonjs' ||
94+ type === TYPE_COMMONJS && asyncESM . typeFlag === 'module' ) {
95+ throw new ERR_TYPE_MISMATCH (
96+ fileURLToPath ( url ) , ext , asyncESM . typeFlag , 'scope' ) ;
97+ }
98+ }
99+ }
100+ if ( ! format ) {
101+ if ( isMain && asyncESM . typeFlag )
102+ format = asyncESM . typeFlag ;
103+ else if ( isMain )
104+ format = type === TYPE_MODULE ? 'module' : 'commonjs' ;
105+ else
106+ throw new ERR_UNKNOWN_FILE_EXTENSION ( fileURLToPath ( url ) ,
107+ fileURLToPath ( parentURL ) ) ;
108+ }
143109 return { url : `${ url } ` , format } ;
144110}
145111
0 commit comments