@@ -583,24 +583,86 @@ var AMDLoader;
583583 } ( ) ) ;
584584 var NodeScriptLoader = ( function ( ) {
585585 function NodeScriptLoader ( ) {
586- this . _initialized = false ;
586+ this . _didInitialize = false ;
587+ this . _didPatchNodeRequire = false ;
588+ // js-flags have an impact on cached data
589+ this . _jsflags = '' ;
590+ for ( var _i = 0 , _a = process . argv ; _i < _a . length ; _i ++ ) {
591+ var arg = _a [ _i ] ;
592+ if ( arg . indexOf ( '--js-flags=' ) === 0 ) {
593+ this . _jsflags = arg ;
594+ break ;
595+ }
596+ }
587597 }
588598 NodeScriptLoader . prototype . _init = function ( nodeRequire ) {
589- if ( this . _initialized ) {
599+ if ( this . _didInitialize ) {
590600 return ;
591601 }
592- this . _initialized = true ;
602+ this . _didInitialize = true ;
593603 this . _fs = nodeRequire ( 'fs' ) ;
594604 this . _vm = nodeRequire ( 'vm' ) ;
595605 this . _path = nodeRequire ( 'path' ) ;
596606 this . _crypto = nodeRequire ( 'crypto' ) ;
597607 } ;
608+ // patch require-function of nodejs such that we can manually create a script
609+ // from cached data. this is done by overriding the `Module._compile` function
610+ NodeScriptLoader . prototype . _initNodeRequire = function ( nodeRequire , moduleManager ) {
611+ var nodeCachedDataDir = moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedDataDir ;
612+ if ( ! nodeCachedDataDir || this . _didPatchNodeRequire ) {
613+ return ;
614+ }
615+ this . _didPatchNodeRequire = true ;
616+ var that = this ;
617+ var Module = nodeRequire ( 'module' ) ;
618+ function makeRequireFunction ( mod ) {
619+ var Module = mod . constructor ;
620+ var require = function require ( path ) {
621+ try {
622+ return mod . require ( path ) ;
623+ }
624+ finally {
625+ // nothing
626+ }
627+ } ;
628+ require . resolve = function resolve ( request ) {
629+ return Module . _resolveFilename ( request , mod ) ;
630+ } ;
631+ require . main = process . mainModule ;
632+ require . extensions = Module . _extensions ;
633+ require . cache = Module . _cache ;
634+ return require ;
635+ }
636+ Module . prototype . _compile = function ( content , filename ) {
637+ // remove shebang
638+ content = content . replace ( / ^ # ! .* / , '' ) ;
639+ // create wrapper function
640+ var wrapper = Module . wrap ( content ) ;
641+ var cachedDataPath = that . _getCachedDataPath ( nodeCachedDataDir , filename ) ;
642+ var options = { filename : filename } ;
643+ try {
644+ options . cachedData = that . _fs . readFileSync ( cachedDataPath ) ;
645+ }
646+ catch ( e ) {
647+ options . produceCachedData = true ;
648+ }
649+ var script = new that . _vm . Script ( wrapper , options ) ;
650+ var compileWrapper = script . runInThisContext ( options ) ;
651+ var dirname = that . _path . dirname ( filename ) ;
652+ var require = makeRequireFunction ( this ) ;
653+ var args = [ this . exports , require , this , filename , dirname , process , AMDLoader . global , Buffer ] ;
654+ var result = compileWrapper . apply ( this . exports , args ) ;
655+ that . _processCachedData ( moduleManager , script , cachedDataPath ) ;
656+ return result ;
657+ } ;
658+ } ;
598659 NodeScriptLoader . prototype . load = function ( moduleManager , scriptSrc , callback , errorback ) {
599660 var _this = this ;
600661 var opts = moduleManager . getConfig ( ) . getOptionsLiteral ( ) ;
601662 var nodeRequire = ( opts . nodeRequire || AMDLoader . global . nodeRequire ) ;
602663 var nodeInstrumenter = ( opts . nodeInstrumenter || function ( c ) { return c ; } ) ;
603664 this . _init ( nodeRequire ) ;
665+ this . _initNodeRequire ( nodeRequire , moduleManager ) ;
604666 var recorder = moduleManager . getRecorder ( ) ;
605667 if ( / ^ n o d e \| / . test ( scriptSrc ) ) {
606668 var pieces = scriptSrc . split ( '|' ) ;
@@ -646,44 +708,16 @@ var AMDLoader;
646708 }
647709 else {
648710 var cachedDataPath_1 = _this . _getCachedDataPath ( opts . nodeCachedDataDir , scriptSrc ) ;
649- _this . _fs . readFile ( cachedDataPath_1 , function ( err , data ) {
711+ _this . _fs . readFile ( cachedDataPath_1 , function ( err , cachedData ) {
650712 // create script options
651- var scriptOptions = {
713+ var options = {
652714 filename : vmScriptSrc ,
653- produceCachedData : typeof data === 'undefined' ,
654- cachedData : data
715+ produceCachedData : typeof cachedData === 'undefined' ,
716+ cachedData : cachedData
655717 } ;
656- var script = _this . _loadAndEvalScript ( scriptSrc , vmScriptSrc , contents , scriptOptions , recorder ) ;
718+ var script = _this . _loadAndEvalScript ( scriptSrc , vmScriptSrc , contents , options , recorder ) ;
657719 callback ( ) ;
658- // cached code after math
659- if ( script . cachedDataRejected ) {
660- // data rejected => delete cache file
661- opts . onNodeCachedDataError ( {
662- errorCode : 'cachedDataRejected' ,
663- path : cachedDataPath_1
664- } ) ;
665- NodeScriptLoader . _runSoon ( function ( ) { return _this . _fs . unlink ( cachedDataPath_1 , function ( err ) {
666- if ( err ) {
667- moduleManager . getConfig ( ) . getOptionsLiteral ( ) . onNodeCachedDataError ( {
668- errorCode : 'unlink' ,
669- path : cachedDataPath_1 ,
670- detail : err
671- } ) ;
672- }
673- } ) ; } , opts . nodeCachedDataWriteDelay ) ;
674- }
675- else if ( script . cachedDataProduced ) {
676- // data produced => write cache file
677- NodeScriptLoader . _runSoon ( function ( ) { return _this . _fs . writeFile ( cachedDataPath_1 , script . cachedData , function ( err ) {
678- if ( err ) {
679- moduleManager . getConfig ( ) . getOptionsLiteral ( ) . onNodeCachedDataError ( {
680- errorCode : 'writeFile' ,
681- path : cachedDataPath_1 ,
682- detail : err
683- } ) ;
684- }
685- } ) ; } , opts . nodeCachedDataWriteDelay ) ;
686- }
720+ _this . _processCachedData ( moduleManager , script , cachedDataPath_1 ) ;
687721 } ) ;
688722 }
689723 } ) ;
@@ -699,10 +733,41 @@ var AMDLoader;
699733 recorder . record ( AMDLoader . LoaderEventType . NodeEndEvaluatingScript , scriptSrc ) ;
700734 return script ;
701735 } ;
702- NodeScriptLoader . prototype . _getCachedDataPath = function ( baseDir , filename ) {
703- var hash = this . _crypto . createHash ( 'md5' ) . update ( filename , 'utf8' ) . digest ( 'hex' ) ;
736+ NodeScriptLoader . prototype . _getCachedDataPath = function ( basedir , filename ) {
737+ var hash = this . _crypto . createHash ( 'md5' ) . update ( filename , 'utf8' ) . update ( this . _jsflags , 'utf8' ) . digest ( 'hex' ) ;
704738 var basename = this . _path . basename ( filename ) . replace ( / \. j s $ / , '' ) ;
705- return this . _path . join ( baseDir , hash + "-" + basename + ".code" ) ;
739+ return this . _path . join ( basedir , basename + "-" + hash + ".code" ) ;
740+ } ;
741+ NodeScriptLoader . prototype . _processCachedData = function ( moduleManager , script , cachedDataPath ) {
742+ var _this = this ;
743+ if ( script . cachedDataRejected ) {
744+ // data rejected => delete cache file
745+ moduleManager . getConfig ( ) . getOptionsLiteral ( ) . onNodeCachedDataError ( {
746+ errorCode : 'cachedDataRejected' ,
747+ path : cachedDataPath
748+ } ) ;
749+ NodeScriptLoader . _runSoon ( function ( ) { return _this . _fs . unlink ( cachedDataPath , function ( err ) {
750+ if ( err ) {
751+ moduleManager . getConfig ( ) . getOptionsLiteral ( ) . onNodeCachedDataError ( {
752+ errorCode : 'unlink' ,
753+ path : cachedDataPath ,
754+ detail : err
755+ } ) ;
756+ }
757+ } ) ; } , moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedDataWriteDelay ) ;
758+ }
759+ else if ( script . cachedDataProduced ) {
760+ // data produced => write cache file
761+ NodeScriptLoader . _runSoon ( function ( ) { return _this . _fs . writeFile ( cachedDataPath , script . cachedData , function ( err ) {
762+ if ( err ) {
763+ moduleManager . getConfig ( ) . getOptionsLiteral ( ) . onNodeCachedDataError ( {
764+ errorCode : 'writeFile' ,
765+ path : cachedDataPath ,
766+ detail : err
767+ } ) ;
768+ }
769+ } ) ; } , moduleManager . getConfig ( ) . getOptionsLiteral ( ) . nodeCachedDataWriteDelay ) ;
770+ }
706771 } ;
707772 NodeScriptLoader . _runSoon = function ( callback , minTimeout ) {
708773 var timeout = minTimeout + Math . ceil ( Math . random ( ) * minTimeout ) ;
0 commit comments