@@ -34,58 +34,102 @@ export function compileNodeModulesPaths(filePath: string): string[] {
3434 * Poorly implemented shim for Node 8+ `require.resolve()`, with `paths`
3535 * option.
3636 *
37+ * Only supports use case 4: LOAD_NODE_MODULES
38+ *
3739 * @see https://nodejs.org/docs/latest-v8.x/api/modules.html#modules_require_resolve_request_options
3840 * @see https://nodejs.org/docs/latest-v8.x/api/modules.html#modules_all_together
3941 */
40- export function resolve ( pkg : string , options ?: { paths ?: string [ ] } ) : string {
42+ export function resolve ( m : string , options ?: { paths ?: string [ ] } ) : string {
4143 const paths = options && options . paths ? options . paths : undefined ;
4244
4345 if ( ! paths ) {
4446 // There is absolutely no reason to use this shim without the `paths`
4547 // option--use the built-in resolver.
46- return require . resolve ( pkg ) ;
48+ return require . resolve ( m ) ;
4749 }
4850
49- const safeStat = ( filePath : string ) : fs . Stats | undefined => {
50- try {
51- return fs . statSync ( filePath ) ;
52- } catch ( e ) {
53- // ignore
51+ // LOAD_NODE_MODULES
52+ for ( const p of paths ) {
53+ const filePath = path . join ( p , m ) ;
54+ const foundPathAsFile = resolve . LOAD_AS_FILE ( filePath ) ;
55+
56+ if ( foundPathAsFile ) {
57+ return foundPathAsFile ;
5458 }
55- } ;
5659
57- for ( const p of paths ) {
58- const filePath = path . join ( p , pkg ) ;
60+ const foundPathAsDirectory = resolve . LOAD_AS_DIRECTORY ( filePath ) ;
5961
60- const filePaths = [ filePath , filePath + '.js' , filePath + '.json' ] ;
61- const stats = filePaths . map ( ( p ) : [ string , fs . Stats | undefined ] => [ p , safeStat ( p ) ] ) ;
62- const found = stats . find ( ( [ p , s ] ) => typeof s !== 'undefined' && s . isFile ( ) ) ;
62+ if ( foundPathAsDirectory ) {
63+ return foundPathAsDirectory ;
64+ }
65+ }
6366
64- if ( found ) {
65- return found [ 0 ] ;
67+ const err : NodeJS . ErrnoException = new Error ( `Cannot find module '${ m } '` ) ;
68+ err . code = 'MODULE_NOT_FOUND' ;
69+ throw err ;
70+ }
71+
72+ export namespace resolve {
73+ export function LOAD_AS_FILE ( x : string ) : string | undefined {
74+ const exts = [ '' , '.js' , '.json' ] ;
75+
76+ for ( const ext of exts ) {
77+ const p = x + ext ;
78+ const stat = safeStatSync ( p ) ;
79+
80+ if ( stat && stat . isFile ( ) ) {
81+ return p ;
82+ }
6683 }
84+ }
6785
68- const [ [ , stat ] ] = stats ;
86+ export function LOAD_INDEX ( x : string ) : string | undefined {
87+ const exts = [ '.js' , '.json' ] ;
6988
70- if ( stat && stat . isDirectory ( ) ) {
71- try {
72- const packageJson = JSON . parse ( fs . readFileSync ( path . join ( filePath , 'package.json' ) , { encoding : 'utf8' } ) ) ;
89+ for ( const ext of exts ) {
90+ const p = path . join ( x , `index ${ ext } ` ) ;
91+ const stat = safeStatSync ( p ) ;
7392
74- if ( packageJson . main ) {
75- const mainPath = path . join ( filePath , packageJson . main ) ;
76- const mainStat = safeStat ( mainPath ) ;
93+ if ( stat && stat . isFile ( ) ) {
94+ return p ;
95+ }
96+ }
97+ }
98+
99+ export function LOAD_AS_DIRECTORY ( x : string ) : string | undefined {
100+ try {
101+ const packageJson = JSON . parse ( fs . readFileSync ( path . join ( x , 'package.json' ) , { encoding : 'utf8' } ) ) ;
102+
103+ if ( packageJson . main ) {
104+ const m = path . join ( x , packageJson . main ) ;
105+ const foundPathAsFile = resolve . LOAD_AS_FILE ( m ) ;
106+
107+ if ( foundPathAsFile ) {
108+ return foundPathAsFile ;
109+ }
110+
111+ const foundPathAsIndex = resolve . LOAD_INDEX ( m ) ;
77112
78- if ( mainStat && mainStat . isFile ( ) ) {
79- return mainPath ;
80- }
113+ if ( foundPathAsIndex ) {
114+ return foundPathAsIndex ;
81115 }
82- } catch ( e ) {
83- // ignore
84116 }
117+ } catch ( e ) {
118+ // ignore fs and json errors
119+ }
120+
121+ const foundPath = resolve . LOAD_INDEX ( x ) ;
122+
123+ if ( foundPath ) {
124+ return foundPath ;
85125 }
86126 }
127+ }
87128
88- const err : NodeJS . ErrnoException = new Error ( `Cannot find module '${ pkg } '` ) ;
89- err . code = 'MODULE_NOT_FOUND' ;
90- throw err ;
129+ function safeStatSync ( filePath : string ) : fs . Stats | undefined {
130+ try {
131+ return fs . statSync ( filePath ) ;
132+ } catch ( e ) {
133+ // ignore
134+ }
91135}
0 commit comments