11import * as vm from 'vm' ;
22import * as path from 'path' ;
3+ import { RawSource } from 'webpack-sources' ;
34
45const NodeTemplatePlugin = require ( 'webpack/lib/node/NodeTemplatePlugin' ) ;
56const NodeTargetPlugin = require ( 'webpack/lib/node/NodeTargetPlugin' ) ;
@@ -53,12 +54,7 @@ export class WebpackResourceLoader {
5354 new LoaderTargetPlugin ( 'node' )
5455 ) ;
5556
56- // Store the result of the parent compilation before we start the child compilation
57- let assetsBeforeCompilation = Object . assign (
58- { } ,
59- this . _parentCompilation . assets [ outputOptions . filename ]
60- ) ;
61-
57+ // NOTE: This is not needed with webpack 3.6+
6258 // Fix for "Uncaught TypeError: __webpack_require__(...) is not a function"
6359 // Hot module replacement requires that every child compiler has its own
6460 // cache. @see https://github.com/ampedandwired/html-webpack-plugin/pull/179
@@ -71,9 +67,25 @@ export class WebpackResourceLoader {
7167 }
7268 } ) ;
7369
70+ childCompiler . plugin ( 'this-compilation' , ( compilation : any ) => {
71+ compilation . plugin ( 'additional-assets' , ( callback : ( err ?: Error ) => void ) => {
72+ const asset = compilation . assets [ filePath ] ;
73+ if ( asset ) {
74+ this . _evaluate ( { outputName : filePath , source : asset . source ( ) } )
75+ . then ( output => {
76+ compilation . assets [ filePath ] = new RawSource ( output ) ;
77+ callback ( ) ;
78+ } )
79+ . catch ( err => callback ( err ) ) ;
80+ } else {
81+ callback ( ) ;
82+ }
83+ } ) ;
84+ } ) ;
85+
7486 // Compile and return a promise
7587 return new Promise ( ( resolve , reject ) => {
76- childCompiler . runAsChild ( ( err : Error , entries : any [ ] , childCompilation : any ) => {
88+ childCompiler . compile ( ( err : Error , childCompilation : any ) => {
7789 // Resolve / reject the promise
7890 if ( childCompilation && childCompilation . errors && childCompilation . errors . length ) {
7991 const errorDetails = childCompilation . errors . map ( function ( error : any ) {
@@ -83,47 +95,30 @@ export class WebpackResourceLoader {
8395 } else if ( err ) {
8496 reject ( err ) ;
8597 } else {
86- // Replace [hash] placeholders in filename
87- const outputName = this . _parentCompilation . mainTemplate . applyPluginsWaterfall (
88- 'asset-path' , outputOptions . filename , {
89- hash : childCompilation . hash ,
90- chunk : entries [ 0 ]
91- } ) ;
92-
93- // Restore the parent compilation to the state like it was before the child compilation.
94- Object . keys ( childCompilation . assets ) . forEach ( ( fileName ) => {
95- // If it wasn't there and it's a source file (absolute path) - delete it.
96- if ( assetsBeforeCompilation [ fileName ] === undefined && path . isAbsolute ( fileName ) ) {
97- delete this . _parentCompilation . assets [ fileName ] ;
98- } else {
99- // Otherwise, add it to the parent compilation.
100- this . _parentCompilation . assets [ fileName ] = childCompilation . assets [ fileName ] ;
98+ Object . keys ( childCompilation . assets ) . forEach ( assetName => {
99+ if ( assetName !== filePath && this . _parentCompilation . assets [ assetName ] == undefined ) {
100+ this . _parentCompilation . assets [ assetName ] = childCompilation . assets [ assetName ] ;
101101 }
102102 } ) ;
103103
104104 // Save the dependencies for this resource.
105- this . _resourceDependencies . set ( outputName , childCompilation . fileDependencies ) ;
105+ this . _resourceDependencies . set ( filePath , childCompilation . fileDependencies ) ;
106106
107107 resolve ( {
108108 // Output name.
109- outputName,
109+ outputName : filePath ,
110110 // Compiled code.
111- source : childCompilation . assets [ outputName ] . source ( )
111+ source : childCompilation . assets [ filePath ] . source ( )
112112 } ) ;
113113 }
114114 } ) ;
115115 } ) ;
116116 }
117117
118- private _evaluate ( output : CompilationOutput ) : Promise < string > {
118+ private _evaluate ( { outputName , source } : CompilationOutput ) : Promise < string > {
119119 try {
120- const outputName = output . outputName ;
121- const vmContext = vm . createContext ( Object . assign ( { require : require } , global ) ) ;
122- const vmScript = new vm . Script ( output . source , { filename : outputName } ) ;
123-
124- // Evaluate code and cast to string
125- let evaluatedSource : string ;
126- evaluatedSource = vmScript . runInContext ( vmContext ) ;
120+ // Evaluate code
121+ const evaluatedSource = vm . runInNewContext ( source , undefined , { filename : outputName } ) ;
127122
128123 if ( typeof evaluatedSource == 'string' ) {
129124 return Promise . resolve ( evaluatedSource ) ;
@@ -137,6 +132,6 @@ export class WebpackResourceLoader {
137132
138133 get ( filePath : string ) : Promise < string > {
139134 return this . _compile ( filePath )
140- . then ( ( result : CompilationOutput ) => this . _evaluate ( result ) ) ;
135+ . then ( ( result : CompilationOutput ) => result . source ) ;
141136 }
142137}
0 commit comments