11// @flow
22import * as pathUtils from 'common/utils/path' ;
3+ import resolve from 'browser-resolve' ;
34
45import type { Module } from '../entities/module' ;
5- import type { Manifest } from '../manager' ;
6+ import Manager from '../manager' ;
67
78import DependencyNotFoundError from '../../errors/dependency-not-found-error' ;
8- import nodeResolvePath from '../utils/node-resolve-path ' ;
9+ import getDependencyName from '../utils/get-dependency-name ' ;
910
1011type Meta = {
1112 [ path : string ] : any ,
@@ -21,88 +22,151 @@ type Packages = {
2122type MetaFiles = Array < { path : string , files ?: MetaFiles } > ;
2223
2324const metas : Metas = { } ;
25+ let combinedMetas : Meta = { } ;
2426const packages : Packages = { } ;
2527
26- function normalize ( files : MetaFiles , fileObject : Meta = { } ) {
28+ export function getCombinedMetas ( ) {
29+ return combinedMetas ;
30+ }
31+
32+ function normalize ( depName : string , files : MetaFiles , fileObject : Meta = { } ) {
2733 for ( let i = 0 ; i < files . length ; i += 1 ) {
28- fileObject [ files [ i ] . path ] = true ; // eslint-disable-line no-param-reassign
34+ const absolutePath = pathUtils . join (
35+ '/node_modules' ,
36+ depName ,
37+ files [ i ] . path
38+ ) ;
39+ fileObject [ absolutePath ] = true ; // eslint-disable-line no-param-reassign
2940
3041 if ( files [ i ] . files ) {
31- normalize ( files [ i ] . files , fileObject ) ;
42+ normalize ( depName , files [ i ] . files , fileObject ) ;
3243 }
3344 }
3445
3546 return fileObject ;
3647}
3748
3849function getMeta ( name : string , version : string ) {
39- if ( metas [ `${ name } @${ version } ` ] ) {
40- return metas [ `${ name } @${ version } ` ] ;
50+ const id = `${ name } @${ version } ` ;
51+ if ( metas [ id ] ) {
52+ return metas [ id ] ;
4153 }
4254
43- return window
55+ metas [ id ] = window
4456 . fetch ( `https://unpkg.com/${ name } @${ version } /?meta` )
4557 . then ( x => x . json ( ) )
46- . then ( metaInfo => {
47- const normalizedMetaInfo = normalize ( metaInfo . files ) ;
48- // rewrite to path: any object
49- metas [ `${ name } @${ version } ` ] = normalizedMetaInfo ;
50-
51- return normalizedMetaInfo ;
58+ . then ( metaInfo => normalize ( name , metaInfo . files ) )
59+ . then ( normalizedMetas => {
60+ combinedMetas = { ...combinedMetas , ...normalizedMetas } ;
61+ return normalizedMetas ;
5262 } ) ;
63+
64+ return metas [ id ] ;
5365}
5466
55- export default async function fetchModule (
56- path : string ,
57- manifest : Manifest ,
58- defaultExtensions : Array < string > = [ 'js' , 'jsx' , 'json' ]
59- ) : Promise < Module > {
67+ function downloadDependency ( depName : string , depVersion : string , path : string ) {
6068 if ( packages [ path ] ) {
6169 return packages [ path ] ;
6270 }
6371
72+ const relativePath = path . replace (
73+ pathUtils . join ( '/node_modules' , depName ) ,
74+ ''
75+ ) ;
76+
77+ packages [ path ] = window
78+ . fetch ( `https://unpkg.com/${ depName } @${ depVersion } ${ relativePath } ` )
79+ . then ( x => {
80+ if ( x . ok ) {
81+ return x . text ( ) ;
82+ }
83+
84+ return `throw new Error("Could not find module ${ path } ` ;
85+ } )
86+ . then ( x => ( {
87+ path,
88+ code : x ,
89+ } ) ) ;
90+
91+ return packages [ path ] ;
92+ }
93+
94+ export default async function fetchModule (
95+ path : string ,
96+ currentPath : string ,
97+ manager : Manager ,
98+ defaultExtensions : Array < string > = [ 'js' , 'jsx' , 'json' ]
99+ ) : Promise < Module > {
64100 const installedDependencies = {
65- ...manifest . dependencies . reduce (
101+ ...manager . manifest . dependencies . reduce (
66102 ( t , n ) => ( { ...t , [ n . name ] : n . version } ) ,
67103 { }
68104 ) ,
69- ...manifest . dependencyDependencies ,
105+ ...manager . manifest . dependencyDependencies ,
70106 } ;
71107
72- const dependencyParts = path . split ( '/' ) ;
73- const dependencyName = path . startsWith ( '@' )
74- ? `${ dependencyParts [ 0 ] } /${ dependencyParts [ 1 ] } `
75- : dependencyParts [ 0 ] ;
108+ const dependencyName = getDependencyName ( path ) ;
76109
77110 const version = installedDependencies [ dependencyName ] ;
78111
79112 if ( ! version ) {
80113 throw new DependencyNotFoundError ( path ) ;
81114 }
82115
83- const meta = await getMeta ( dependencyName , version ) ;
84-
85- const resolvedPath = nodeResolvePath (
86- path . replace ( dependencyName , '' ) ,
87- meta ,
88- defaultExtensions
89- ) ;
90-
91- return window
92- . fetch ( `https://unpkg.com/${ dependencyName } @${ version } ${ resolvedPath } ` )
93- . then ( x => {
94- if ( x . ok ) {
95- return x . text ( ) ;
116+ const meta = await getMeta ( dependencyName , version . resolved ) ;
117+
118+ return new Promise ( ( res , reject ) => {
119+ resolve (
120+ path ,
121+ {
122+ filename : currentPath ,
123+ extensions : defaultExtensions . map ( ext => '.' + ext ) ,
124+ isFile : ( p , c ) => c ( null , ! ! manager . transpiledModules [ p ] || ! ! meta [ p ] ) ,
125+ readFile : async ( p , c , cb ) => {
126+ const callback = cb || c ;
127+ if ( manager . transpiledModules [ p ] ) {
128+ return callback ( null , manager . transpiledModules [ p ] . module . code ) ;
129+ }
130+
131+ const depName = getDependencyName ( p ) ;
132+ const depInfo = manager . manifest . dependencyDependencies [ depName ] ;
133+
134+ if ( depInfo ) {
135+ try {
136+ const module = await downloadDependency (
137+ depName ,
138+ depInfo . resolved ,
139+ p
140+ ) ;
141+
142+ if ( module ) {
143+ manager . addModule ( module ) ;
144+
145+ callback ( null , module . code ) ;
146+ return null ;
147+ }
148+ } catch ( e ) {
149+ // Let it throw the error
150+ }
151+ }
152+
153+ const err = new Error ( 'Could not find ' + p ) ;
154+ err . code = 'ENOENT' ;
155+
156+ callback ( err ) ;
157+ return null ;
158+ } ,
159+ } ,
160+ ( err , resolvedPath ) => {
161+ if ( err ) {
162+ console . error ( err ) ;
163+ return reject ( err ) ;
164+ }
165+
166+ return res (
167+ downloadDependency ( dependencyName , version . resolved , resolvedPath )
168+ ) ;
96169 }
97-
98- return `throw new Error("Could not find module ${ path } ` ;
99- } )
100- . then ( x => ( {
101- path : pathUtils . join ( '/node_modules' , dependencyName , resolvedPath ) ,
102- code : x ,
103- } ) )
104- . then ( module => {
105- packages [ path ] = module ;
106- return module ;
107- } ) ;
170+ ) ;
171+ } ) ;
108172}
0 commit comments