1
1
import * as vm from 'vm' ;
2
2
import * as path from 'path' ;
3
+ import { OriginalSource } from 'webpack-sources' ;
3
4
4
5
const NodeTemplatePlugin = require ( 'webpack/lib/node/NodeTemplatePlugin' ) ;
5
6
const NodeTargetPlugin = require ( 'webpack/lib/node/NodeTargetPlugin' ) ;
@@ -53,12 +54,7 @@ export class WebpackResourceLoader {
53
54
new LoaderTargetPlugin ( 'node' )
54
55
) ;
55
56
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+
62
58
// Fix for "Uncaught TypeError: __webpack_require__(...) is not a function"
63
59
// Hot module replacement requires that every child compiler has its own
64
60
// cache. @see https://github.com/ampedandwired/html-webpack-plugin/pull/179
@@ -71,9 +67,25 @@ export class WebpackResourceLoader {
71
67
}
72
68
} ) ;
73
69
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 OriginalSource ( output , filePath ) ;
77
+ callback ( ) ;
78
+ } )
79
+ . catch ( err => callback ( err ) ) ;
80
+ } else {
81
+ callback ( ) ;
82
+ }
83
+ } ) ;
84
+ } ) ;
85
+
74
86
// Compile and return a promise
75
87
return new Promise ( ( resolve , reject ) => {
76
- childCompiler . runAsChild ( ( err : Error , entries : any [ ] , childCompilation : any ) => {
88
+ childCompiler . compile ( ( err : Error , childCompilation : any ) => {
77
89
// Resolve / reject the promise
78
90
if ( childCompilation && childCompilation . errors && childCompilation . errors . length ) {
79
91
const errorDetails = childCompilation . errors . map ( function ( error : any ) {
@@ -83,47 +95,30 @@ export class WebpackResourceLoader {
83
95
} else if ( err ) {
84
96
reject ( err ) ;
85
97
} 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 ] ;
101
101
}
102
102
} ) ;
103
103
104
104
// Save the dependencies for this resource.
105
- this . _resourceDependencies . set ( outputName , childCompilation . fileDependencies ) ;
105
+ this . _resourceDependencies . set ( filePath , childCompilation . fileDependencies ) ;
106
106
107
107
resolve ( {
108
108
// Output name.
109
- outputName,
109
+ outputName : filePath ,
110
110
// Compiled code.
111
- source : childCompilation . assets [ outputName ] . source ( )
111
+ source : childCompilation . assets [ filePath ] . source ( )
112
112
} ) ;
113
113
}
114
114
} ) ;
115
115
} ) ;
116
116
}
117
117
118
- private _evaluate ( output : CompilationOutput ) : Promise < string > {
118
+ private _evaluate ( { outputName , source } : CompilationOutput ) : Promise < string > {
119
119
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 } ) ;
127
122
128
123
if ( typeof evaluatedSource == 'string' ) {
129
124
return Promise . resolve ( evaluatedSource ) ;
@@ -137,6 +132,6 @@ export class WebpackResourceLoader {
137
132
138
133
get ( filePath : string ) : Promise < string > {
139
134
return this . _compile ( filePath )
140
- . then ( ( result : CompilationOutput ) => this . _evaluate ( result ) ) ;
135
+ . then ( ( result : CompilationOutput ) => result . source ) ;
141
136
}
142
137
}
0 commit comments