@@ -9,6 +9,7 @@ import { ParsedConfigurationFiles } from '@codesandbox/common/lib/templates/temp
9
9
import DependencyNotFoundError from 'sandbox-hooks/errors/dependency-not-found-error' ;
10
10
import ModuleNotFoundError from 'sandbox-hooks/errors/module-not-found-error' ;
11
11
12
+ import { generateBenchmarkInterface } from '../utils/benchmark' ;
12
13
import { Module } from './types/module' ;
13
14
import TranspiledModule , {
14
15
ChildModule ,
@@ -28,6 +29,7 @@ import { packageFilter } from './utils/resolve-utils';
28
29
import { ignoreNextCache , deleteAPICache , clearIndexedDBCache } from './cache' ;
29
30
import { shouldTranspile } from './transpilers/babel/check' ;
30
31
import { splitQueryFromPath } from './utils/query-path' ;
32
+ import { measure , endMeasure } from '../utils/metrics' ;
31
33
32
34
declare const BrowserFS : any ;
33
35
@@ -122,7 +124,10 @@ export default class Manager {
122
124
fileResolver : IFileResolver | undefined ;
123
125
124
126
// List of modules that are being transpiled, to prevent duplicate jobs.
125
- transpileJobs : { [ transpiledModuleId : string ] : true } ;
127
+ transpileJobs : {
128
+ [ transpiledModuleId : string ] : true | Promise < TranspiledModule > ;
129
+ } ;
130
+
126
131
transpiledModulesByHash : { [ hash : string ] : TranspiledModule } ;
127
132
128
133
// All paths are resolved at least twice: during transpilation and evaluation.
@@ -161,6 +166,9 @@ export default class Manager {
161
166
if ( process . env . NODE_ENV === 'development' ) {
162
167
// eslint-disable-next-line no-console
163
168
console . log ( this ) ;
169
+
170
+ // Initialize benchmark logic
171
+ getGlobal ( ) . Benchmark = generateBenchmarkInterface ( this ) ;
164
172
}
165
173
166
174
BrowserFS . configure (
@@ -266,7 +274,7 @@ export default class Manager {
266
274
return this . fileResolver . readFile ( p ) . then ( code => {
267
275
this . addModule ( { code, path : p } ) ;
268
276
269
- callback ( code ) ;
277
+ callback ( null , code ) ;
270
278
} ) ;
271
279
}
272
280
@@ -499,6 +507,10 @@ export default class Manager {
499
507
this . getTranspiledModules ( ) . map ( tModule => tModule . resetCompilation ( ) ) ;
500
508
}
501
509
510
+ clearTranspilationCache ( ) {
511
+ this . getTranspiledModules ( ) . map ( tModule => tModule . resetTranspilation ( ) ) ;
512
+ }
513
+
502
514
getModules ( ) : Array < Module | ChildModule > {
503
515
return values ( this . transpiledModules ) . map ( t => t . module ) ;
504
516
}
@@ -587,102 +599,111 @@ export default class Manager {
587
599
currentPath : string ,
588
600
defaultExtensions = [ 'js' , 'jsx' , 'json' ]
589
601
) : Promise < Module > {
590
- return new Promise ( promiseResolve => {
591
- const dirredPath = pathUtils . dirname ( currentPath ) ;
592
- if ( this . cachedPaths [ dirredPath ] === undefined ) {
593
- this . cachedPaths [ dirredPath ] = { } ;
594
- }
602
+ const dirredPath = pathUtils . dirname ( currentPath ) ;
603
+ if ( this . cachedPaths [ dirredPath ] === undefined ) {
604
+ this . cachedPaths [ dirredPath ] = { } ;
605
+ }
595
606
596
- const cachedPath = this . cachedPaths [ dirredPath ] [ path ] ;
607
+ const cachedPath = this . cachedPaths [ dirredPath ] [ path ] ;
597
608
598
- let resolvedPath ;
609
+ if ( cachedPath ) {
610
+ return Promise . resolve ( this . transpiledModules [ cachedPath ] . module ) ;
611
+ }
599
612
600
- if ( cachedPath ) {
601
- resolvedPath = cachedPath ;
602
- } else {
603
- const presetAliasedPath = this . getPresetAliasedPath ( path ) ;
613
+ const measureKey = `resolve-async: ${ path } : ${ currentPath } ` ;
614
+ return new Promise ( ( promiseResolve , promiseReject ) => {
615
+ measure ( measureKey ) ;
616
+ const presetAliasedPath = this . getPresetAliasedPath ( path ) ;
604
617
605
- const aliasedPath = this . getAliasedDependencyPath (
606
- presetAliasedPath ,
607
- currentPath
608
- ) ;
609
- const shimmedPath = coreLibraries [ aliasedPath ] || aliasedPath ;
618
+ const aliasedPath = this . getAliasedDependencyPath (
619
+ presetAliasedPath ,
620
+ currentPath
621
+ ) ;
622
+ const shimmedPath = coreLibraries [ aliasedPath ] || aliasedPath ;
610
623
611
- if ( NODE_LIBS . indexOf ( shimmedPath ) > - 1 ) {
612
- this . cachedPaths [ dirredPath ] [ path ] = shimmedPath ;
613
- promiseResolve ( getShimmedModuleFromPath ( currentPath , path ) ) ;
614
- return ;
615
- }
624
+ if ( NODE_LIBS . indexOf ( shimmedPath ) > - 1 ) {
625
+ this . cachedPaths [ dirredPath ] [ path ] = shimmedPath ;
626
+ promiseResolve ( getShimmedModuleFromPath ( currentPath , path ) ) ;
627
+ return ;
628
+ }
616
629
617
- try {
618
- resolve (
619
- shimmedPath ,
620
- {
621
- filename : currentPath ,
622
- extensions : defaultExtensions . map ( ext => '.' + ext ) ,
623
- isFile : this . isFile ,
624
- readFileSync : this . readFileSync ,
625
- packageFilter,
626
- moduleDirectory : this . getModuleDirectories ( ) ,
627
- } ,
628
- ( err , foundPath ) => {
629
- if ( err ) {
630
- throw err ;
631
- }
630
+ resolve (
631
+ shimmedPath ,
632
+ {
633
+ filename : currentPath ,
634
+ extensions : defaultExtensions . map ( ext => '.' + ext ) ,
635
+ isFile : this . isFile ,
636
+ readFileSync : this . readFileSync ,
637
+ packageFilter,
638
+ moduleDirectory : this . getModuleDirectories ( ) ,
639
+ } ,
640
+ ( err , foundPath ) => {
641
+ endMeasure ( measureKey , { silent : true } ) ;
642
+ if ( err ) {
643
+ if (
644
+ this . cachedPaths [ dirredPath ] &&
645
+ this . cachedPaths [ dirredPath ] [ path ]
646
+ ) {
647
+ delete this . cachedPaths [ dirredPath ] [ path ] ;
648
+ }
632
649
633
- this . cachedPaths [ dirredPath ] [ path ] = foundPath ;
650
+ let connectedPath = shimmedPath ;
651
+ if ( connectedPath . indexOf ( '/node_modules' ) !== 0 ) {
652
+ connectedPath = / ^ ( \w | @ \w ) / . test ( shimmedPath )
653
+ ? pathUtils . join ( '/node_modules' , shimmedPath )
654
+ : pathUtils . join ( pathUtils . dirname ( currentPath ) , shimmedPath ) ;
655
+ }
634
656
635
- if ( foundPath === '//empty.js' ) {
636
- promiseResolve ( getShimmedModuleFromPath ( currentPath , path ) ) ;
637
- return ;
638
- }
657
+ const isDependency = connectedPath . includes ( '/node_modules/' ) ;
639
658
640
- if ( ! this . transpiledModules [ foundPath ] ) {
641
- this . readFileSync ( foundPath , code => {
642
- this . addModule ( { path : foundPath , code } ) ;
643
- promiseResolve ( this . transpiledModules [ foundPath ] . module ) ;
644
- } ) ;
645
- } else {
646
- promiseResolve ( this . transpiledModules [ foundPath ] . module ) ;
647
- }
659
+ connectedPath = connectedPath . replace ( '/node_modules/' , '' ) ;
660
+
661
+ if ( ! isDependency ) {
662
+ promiseReject (
663
+ new ModuleNotFoundError ( shimmedPath , false , currentPath )
664
+ ) ;
648
665
}
649
- ) ;
650
- } catch ( e ) {
651
- if (
652
- this . cachedPaths [ dirredPath ] &&
653
- this . cachedPaths [ dirredPath ] [ path ]
654
- ) {
655
- delete this . cachedPaths [ dirredPath ] [ path ] ;
656
- }
657
666
658
- let connectedPath = shimmedPath ;
659
- if ( connectedPath . indexOf ( '/node_modules' ) !== 0 ) {
660
- connectedPath = / ^ ( \w | @ \w ) / . test ( shimmedPath )
661
- ? pathUtils . join ( '/node_modules' , shimmedPath )
662
- : pathUtils . join ( pathUtils . dirname ( currentPath ) , shimmedPath ) ;
663
- }
667
+ const dependencyName = getDependencyName ( connectedPath ) ;
668
+
669
+ if (
670
+ this . manifest . dependencies . find ( d => d . name === dependencyName ) ||
671
+ this . manifest . dependencyDependencies [ dependencyName ]
672
+ ) {
673
+ promiseReject (
674
+ new ModuleNotFoundError ( connectedPath , true , currentPath )
675
+ ) ;
676
+ } else {
677
+ promiseReject (
678
+ new DependencyNotFoundError ( connectedPath , currentPath )
679
+ ) ;
680
+ }
664
681
665
- const isDependency = connectedPath . includes ( '/node_modules/' ) ;
682
+ return ;
683
+ }
666
684
667
- connectedPath = connectedPath . replace ( '/node_modules/' , '' ) ;
685
+ this . cachedPaths [ dirredPath ] [ path ] = foundPath ;
668
686
669
- if ( ! isDependency ) {
670
- throw new ModuleNotFoundError ( shimmedPath , false , currentPath ) ;
687
+ if ( foundPath === '//empty.js' ) {
688
+ promiseResolve ( getShimmedModuleFromPath ( currentPath , path ) ) ;
689
+ return ;
671
690
}
672
691
673
- const dependencyName = getDependencyName ( connectedPath ) ;
692
+ if ( ! this . transpiledModules [ foundPath ] ) {
693
+ this . readFileSync ( foundPath , ( error , code ) => {
694
+ if ( error ) {
695
+ promiseReject ( error ) ;
696
+ return ;
697
+ }
674
698
675
- if (
676
- this . manifest . dependencies . find ( d => d . name === dependencyName ) ||
677
- this . manifest . dependencyDependencies [ dependencyName ]
678
- ) {
679
- throw new ModuleNotFoundError ( connectedPath , true , currentPath ) ;
699
+ this . addModule ( { path : foundPath , code } ) ;
700
+ promiseResolve ( this . transpiledModules [ foundPath ] . module ) ;
701
+ } ) ;
680
702
} else {
681
- throw new DependencyNotFoundError ( connectedPath , currentPath ) ;
703
+ promiseResolve ( this . transpiledModules [ foundPath ] . module ) ;
682
704
}
683
705
}
684
- }
685
- promiseResolve ( this . transpiledModules [ resolvedPath ] . module ) ;
706
+ ) ;
686
707
} ) ;
687
708
}
688
709
@@ -704,6 +725,8 @@ export default class Manager {
704
725
if ( cachedPath && this . transpiledModules [ cachedPath ] ) {
705
726
resolvedPath = cachedPath ;
706
727
} else {
728
+ const measureKey = `resolve-sync:${ path } :${ currentPath } ` ;
729
+ measure ( measureKey ) ;
707
730
const presetAliasedPath = this . getPresetAliasedPath ( path ) ;
708
731
709
732
const aliasedPath = this . getAliasedDependencyPath (
@@ -726,6 +749,7 @@ export default class Manager {
726
749
packageFilter,
727
750
moduleDirectory : this . getModuleDirectories ( ) ,
728
751
} ) ;
752
+ endMeasure ( measureKey , { silent : true } ) ;
729
753
730
754
this . cachedPaths [ dirredPath ] [ path ] = resolvedPath ;
731
755
@@ -812,12 +836,10 @@ export default class Manager {
812
836
const tModule =
813
837
currentTModule || this . getTranspiledModule ( this . modules [ '/package.json' ] ) ; // Get arbitrary file from root
814
838
try {
815
- return Promise . resolve (
816
- this . resolveTranspiledModule (
817
- path ,
818
- tModule . module . path ,
819
- ignoredExtensions
820
- )
839
+ return this . resolveTranspiledModule (
840
+ path ,
841
+ tModule . module . path ,
842
+ ignoredExtensions
821
843
) ;
822
844
} catch ( e ) {
823
845
if ( e . type === 'module-not-found' && e . isDependency ) {
0 commit comments