@@ -3,19 +3,21 @@ import * as child_process from "child_process";
3
3
import * as semver from "semver" ;
4
4
import { EventEmitter } from "events" ;
5
5
import { performanceLog } from "../../common/decorators" ;
6
- import { WEBPACK_COMPILATION_COMPLETE } from "../../constants" ;
6
+ import { WEBPACK_COMPILATION_COMPLETE , WEBPACK_PLUGIN_NAME } from "../../constants" ;
7
7
8
8
export class WebpackCompilerService extends EventEmitter implements IWebpackCompilerService {
9
9
private webpackProcesses : IDictionary < child_process . ChildProcess > = { } ;
10
10
private expectedHash : string = null ;
11
11
12
12
constructor (
13
+ private $errors : IErrors ,
13
14
private $childProcess : IChildProcess ,
14
15
public $hooksService : IHooksService ,
15
16
public $hostInfo : IHostInfo ,
16
17
private $logger : ILogger ,
17
18
private $mobileHelper : Mobile . IMobileHelper ,
18
- private $cleanupService : ICleanupService
19
+ private $cleanupService : ICleanupService ,
20
+ private $packageInstallationManager : IPackageInstallationManager
19
21
) { super ( ) ; }
20
22
21
23
public async compileWithWatch ( platformData : IPlatformData , projectData : IProjectData , prepareData : IPrepareData ) : Promise < any > {
@@ -27,67 +29,71 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp
27
29
28
30
let isFirstWebpackWatchCompilation = true ;
29
31
prepareData . watch = true ;
30
- const childProcess = await this . startWebpackProcess ( platformData , projectData , prepareData ) ;
32
+ try {
33
+ const childProcess = await this . startWebpackProcess ( platformData , projectData , prepareData ) ;
31
34
32
- childProcess . on ( "message" , ( message : string | IWebpackEmitMessage ) => {
33
- if ( message === "Webpack compilation complete." ) {
34
- this . $logger . info ( "Webpack build done!" ) ;
35
- resolve ( childProcess ) ;
36
- }
35
+ childProcess . on ( "message" , ( message : string | IWebpackEmitMessage ) => {
36
+ if ( message === "Webpack compilation complete." ) {
37
+ this . $logger . info ( "Webpack build done!" ) ;
38
+ resolve ( childProcess ) ;
39
+ }
37
40
38
- message = message as IWebpackEmitMessage ;
39
- if ( message . emittedFiles ) {
40
- if ( isFirstWebpackWatchCompilation ) {
41
- isFirstWebpackWatchCompilation = false ;
41
+ message = message as IWebpackEmitMessage ;
42
+ if ( message . emittedFiles ) {
43
+ if ( isFirstWebpackWatchCompilation ) {
44
+ isFirstWebpackWatchCompilation = false ;
42
45
this . expectedHash = message . hash ;
43
- return ;
44
- }
46
+ return ;
47
+ }
45
48
46
- let result ;
49
+ let result ;
47
50
48
- if ( prepareData . hmr ) {
51
+ if ( prepareData . hmr ) {
49
52
result = this . getUpdatedEmittedFiles ( message . emittedFiles , message . chunkFiles , message . hash ) ;
50
- } else {
51
- result = { emittedFiles : message . emittedFiles , fallbackFiles : < string [ ] > [ ] , hash : "" } ;
53
+ } else {
54
+ result = { emittedFiles : message . emittedFiles , fallbackFiles : < string [ ] > [ ] , hash : "" } ;
55
+ }
56
+
57
+ const files = result . emittedFiles
58
+ . map ( ( file : string ) => path . join ( platformData . appDestinationDirectoryPath , "app" , file ) ) ;
59
+ const fallbackFiles = result . fallbackFiles
60
+ . map ( ( file : string ) => path . join ( platformData . appDestinationDirectoryPath , "app" , file ) ) ;
61
+
62
+ const data = {
63
+ files,
64
+ hasOnlyHotUpdateFiles : files . every ( f => f . indexOf ( "hot-update" ) > - 1 ) ,
65
+ hmrData : {
66
+ hash : result . hash ,
67
+ fallbackFiles
68
+ } ,
69
+ platform : platformData . platformNameLowerCase
70
+ } ;
71
+
72
+ if ( data . files . length ) {
73
+ this . emit ( WEBPACK_COMPILATION_COMPLETE , data ) ;
74
+ }
52
75
}
76
+ } ) ;
53
77
54
- const files = result . emittedFiles
55
- . map ( ( file : string ) => path . join ( platformData . appDestinationDirectoryPath , "app" , file ) ) ;
56
- const fallbackFiles = result . fallbackFiles
57
- . map ( ( file : string ) => path . join ( platformData . appDestinationDirectoryPath , "app" , file ) ) ;
58
-
59
- const data = {
60
- files,
61
- hasOnlyHotUpdateFiles : files . every ( f => f . indexOf ( "hot-update" ) > - 1 ) ,
62
- hmrData : {
63
- hash : result . hash ,
64
- fallbackFiles
65
- } ,
66
- platform : platformData . platformNameLowerCase
67
- } ;
68
-
69
- if ( data . files . length ) {
70
- this . emit ( WEBPACK_COMPILATION_COMPLETE , data ) ;
71
- }
72
- }
73
- } ) ;
78
+ childProcess . on ( "error" , ( err ) => {
79
+ this . $logger . trace ( `Unable to start webpack process in watch mode. Error is: ${ err } ` ) ;
80
+ delete this . webpackProcesses [ platformData . platformNameLowerCase ] ;
81
+ reject ( err ) ;
82
+ } ) ;
74
83
75
- childProcess . on ( "error" , ( err ) => {
76
- this . $logger . trace ( `Unable to start webpack process in watch mode. Error is: ${ err } ` ) ;
77
- delete this . webpackProcesses [ platformData . platformNameLowerCase ] ;
84
+ childProcess . on ( "close" , async ( arg : any ) => {
85
+ await this . $cleanupService . removeKillProcess ( childProcess . pid . toString ( ) ) ;
86
+
87
+ const exitCode = typeof arg === "number" ? arg : arg && arg . code ;
88
+ this . $logger . trace ( `Webpack process exited with code ${ exitCode } when we expected it to be long living with watch.` ) ;
89
+ const error = new Error ( `Executing webpack failed with exit code ${ exitCode } .` ) ;
90
+ error . code = exitCode ;
91
+ delete this . webpackProcesses [ platformData . platformNameLowerCase ] ;
92
+ reject ( error ) ;
93
+ } ) ;
94
+ } catch ( err ) {
78
95
reject ( err ) ;
79
- } ) ;
80
-
81
- childProcess . on ( "close" , async ( arg : any ) => {
82
- await this . $cleanupService . removeKillProcess ( childProcess . pid . toString ( ) ) ;
83
-
84
- const exitCode = typeof arg === "number" ? arg : arg && arg . code ;
85
- this . $logger . trace ( `Webpack process exited with code ${ exitCode } when we expected it to be long living with watch.` ) ;
86
- const error = new Error ( `Executing webpack failed with exit code ${ exitCode } .` ) ;
87
- error . code = exitCode ;
88
- delete this . webpackProcesses [ platformData . platformNameLowerCase ] ;
89
- reject ( error ) ;
90
- } ) ;
96
+ }
91
97
} ) ;
92
98
}
93
99
@@ -98,26 +104,30 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp
98
104
return ;
99
105
}
100
106
101
- const childProcess = await this . startWebpackProcess ( platformData , projectData , prepareData ) ;
102
- childProcess . on ( "error" , ( err ) => {
103
- this . $logger . trace ( `Unable to start webpack process in non-watch mode. Error is: ${ err } ` ) ;
104
- delete this . webpackProcesses [ platformData . platformNameLowerCase ] ;
107
+ try {
108
+ const childProcess = await this . startWebpackProcess ( platformData , projectData , prepareData ) ;
109
+ childProcess . on ( "error" , ( err ) => {
110
+ this . $logger . trace ( `Unable to start webpack process in non-watch mode. Error is: ${ err } ` ) ;
111
+ delete this . webpackProcesses [ platformData . platformNameLowerCase ] ;
112
+ reject ( err ) ;
113
+ } ) ;
114
+
115
+ childProcess . on ( "close" , async ( arg : any ) => {
116
+ await this . $cleanupService . removeKillProcess ( childProcess . pid . toString ( ) ) ;
117
+
118
+ delete this . webpackProcesses [ platformData . platformNameLowerCase ] ;
119
+ const exitCode = typeof arg === "number" ? arg : arg && arg . code ;
120
+ if ( exitCode === 0 ) {
121
+ resolve ( ) ;
122
+ } else {
123
+ const error = new Error ( `Executing webpack failed with exit code ${ exitCode } .` ) ;
124
+ error . code = exitCode ;
125
+ reject ( error ) ;
126
+ }
127
+ } ) ;
128
+ } catch ( err ) {
105
129
reject ( err ) ;
106
- } ) ;
107
-
108
- childProcess . on ( "close" , async ( arg : any ) => {
109
- await this . $cleanupService . removeKillProcess ( childProcess . pid . toString ( ) ) ;
110
-
111
- delete this . webpackProcesses [ platformData . platformNameLowerCase ] ;
112
- const exitCode = typeof arg === "number" ? arg : arg && arg . code ;
113
- if ( exitCode === 0 ) {
114
- resolve ( ) ;
115
- } else {
116
- const error = new Error ( `Executing webpack failed with exit code ${ exitCode } .` ) ;
117
- error . code = exitCode ;
118
- reject ( error ) ;
119
- }
120
- } ) ;
130
+ }
121
131
} ) ;
122
132
}
123
133
@@ -136,7 +146,7 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp
136
146
@performanceLog ( )
137
147
private async startWebpackProcess ( platformData : IPlatformData , projectData : IProjectData , prepareData : IPrepareData ) : Promise < child_process . ChildProcess > {
138
148
const envData = this . buildEnvData ( platformData . platformNameLowerCase , projectData , prepareData ) ;
139
- const envParams = this . buildEnvCommandLineParams ( envData , platformData , prepareData ) ;
149
+ const envParams = await this . buildEnvCommandLineParams ( envData , platformData , projectData , prepareData ) ;
140
150
const additionalNodeArgs = semver . major ( process . version ) <= 8 ? [ "--harmony" ] : [ ] ;
141
151
142
152
const args = [
@@ -198,14 +208,22 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp
198
208
return envData ;
199
209
}
200
210
201
- private buildEnvCommandLineParams ( envData : any , platformData : IPlatformData , prepareData : IPrepareData ) {
211
+ private async buildEnvCommandLineParams ( envData : any , platformData : IPlatformData , projectData : IProjectData , prepareData : IPrepareData ) {
202
212
const envFlagNames = Object . keys ( envData ) ;
203
- const shouldSnapshot = prepareData . release && ! this . $hostInfo . isWindows && this . $mobileHelper . isAndroidPlatform ( platformData . normalizedPlatformName ) ;
204
- if ( envData && envData . snapshot && ! shouldSnapshot ) {
205
- this . $logger . warn ( "Stripping the snapshot flag. " +
206
- "Bear in mind that snapshot is only available in release builds and " +
207
- "is NOT available on Windows systems." ) ;
208
- envFlagNames . splice ( envFlagNames . indexOf ( "snapshot" ) , 1 ) ;
213
+ const canSnapshot = prepareData . release && this . $mobileHelper . isAndroidPlatform ( platformData . normalizedPlatformName ) ;
214
+ if ( envData && envData . snapshot ) {
215
+ if ( ! canSnapshot ) {
216
+ this . $logger . warn ( "Stripping the snapshot flag. " +
217
+ "Bear in mind that snapshot is only available in Android release builds." ) ;
218
+ envFlagNames . splice ( envFlagNames . indexOf ( "snapshot" ) , 1 ) ;
219
+ } else if ( this . $hostInfo . isWindows ) {
220
+ const minWebpackPluginWithWinSnapshotsVersion = "1.3.0" ;
221
+ const installedWebpackPluginVersion = await this . $packageInstallationManager . getInstalledDependencyVersion ( WEBPACK_PLUGIN_NAME , projectData . projectDir ) ;
222
+ const hasWebpackPluginWithWinSnapshotsSupport = ! ! installedWebpackPluginVersion ? semver . gte ( installedWebpackPluginVersion , minWebpackPluginWithWinSnapshotsVersion ) : true ;
223
+ if ( ! hasWebpackPluginWithWinSnapshotsSupport ) {
224
+ this . $errors . fail ( `In order to generate Snapshots on Windows, please upgrade your Webpack plugin version (npm i nativescript-dev-webpack@latest).` ) ;
225
+ }
226
+ }
209
227
}
210
228
211
229
const args : any [ ] = [ ] ;
0 commit comments