1
1
'use strict' ;
2
2
3
3
/* eslint-disable
4
- import/order,
5
4
no-shadow,
6
5
no-undefined,
7
6
func-names
8
7
*/
9
8
const fs = require ( 'fs' ) ;
10
9
const path = require ( 'path' ) ;
11
-
12
- const ip = require ( 'ip' ) ;
13
10
const tls = require ( 'tls' ) ;
14
11
const url = require ( 'url' ) ;
15
12
const http = require ( 'http' ) ;
16
13
const https = require ( 'https' ) ;
14
+ const ip = require ( 'ip' ) ;
17
15
const sockjs = require ( 'sockjs' ) ;
18
-
19
16
const semver = require ( 'semver' ) ;
20
-
21
17
const killable = require ( 'killable' ) ;
22
-
23
- const del = require ( 'del' ) ;
24
18
const chokidar = require ( 'chokidar' ) ;
25
-
26
19
const express = require ( 'express' ) ;
27
-
28
20
const httpProxyMiddleware = require ( 'http-proxy-middleware' ) ;
29
21
const historyApiFallback = require ( 'connect-history-api-fallback' ) ;
30
22
const compress = require ( 'compression' ) ;
31
23
const serveIndex = require ( 'serve-index' ) ;
32
-
33
24
const webpack = require ( 'webpack' ) ;
34
25
const webpackDevMiddleware = require ( 'webpack-dev-middleware' ) ;
35
-
26
+ const validateOptions = require ( 'schema-utils' ) ;
36
27
const updateCompiler = require ( './utils/updateCompiler' ) ;
37
28
const createLogger = require ( './utils/createLogger' ) ;
38
- const createCertificate = require ( './utils/createCertificate ' ) ;
29
+ const getCertificate = require ( './utils/getCertificate ' ) ;
39
30
const routes = require ( './utils/routes' ) ;
40
-
41
- const validateOptions = require ( 'schema-utils' ) ;
42
31
const schema = require ( './options.json' ) ;
43
32
44
33
// Workaround for sockjs@~0.3.19
@@ -96,43 +85,41 @@ class Server {
96
85
97
86
this . log = _log || createLogger ( options ) ;
98
87
99
- // if the user enables http2, we can safely enable https
100
- if ( options . http2 && ! options . https ) {
101
- options . https = true ;
102
- }
103
-
104
88
this . originalStats =
105
- options . stats && Object . keys ( options . stats ) . length ? options . stats : { } ;
89
+ this . options . stats && Object . keys ( this . options . stats ) . length
90
+ ? this . options . stats
91
+ : { } ;
106
92
107
- this . hot = options . hot || options . hotOnly ;
108
- this . headers = options . headers ;
109
- this . progress = options . progress ;
93
+ this . sockets = [ ] ;
94
+ this . contentBaseWatchers = [ ] ;
110
95
111
- this . serveIndex = options . serveIndex ;
96
+ // TODO this.<property> is deprecated (remove them in next major release.) in favor this.options.<property>
97
+ this . hot = this . options . hot || this . options . hotOnly ;
98
+ this . headers = this . options . headers ;
99
+ this . progress = this . options . progress ;
112
100
113
- this . clientOverlay = options . overlay ;
114
- this . clientLogLevel = options . clientLogLevel ;
101
+ this . serveIndex = this . options . serveIndex ;
115
102
116
- this . publicHost = options . public ;
117
- this . allowedHosts = options . allowedHosts ;
118
- this . disableHostCheck = ! ! options . disableHostCheck ;
103
+ this . clientOverlay = this . options . overlay ;
104
+ this . clientLogLevel = this . options . clientLogLevel ;
119
105
120
- this . sockets = [ ] ;
106
+ this . publicHost = this . options . public ;
107
+ this . allowedHosts = this . options . allowedHosts ;
108
+ this . disableHostCheck = ! ! this . options . disableHostCheck ;
121
109
122
- if ( ! options . watchOptions ) {
123
- options . watchOptions = { } ;
110
+ if ( ! this . options . watchOptions ) {
111
+ this . options . watchOptions = { } ;
124
112
}
125
- // ignoring node_modules folder by default
126
- options . watchOptions . ignored = options . watchOptions . ignored || [
113
+ // Ignoring node_modules folder by default
114
+ this . options . watchOptions . ignored = this . options . watchOptions . ignored || [
127
115
/ n o d e _ m o d u l e s / ,
128
116
] ;
129
- this . watchOptions = options . watchOptions ;
117
+ this . watchOptions = this . options . watchOptions ;
130
118
131
- this . contentBaseWatchers = [ ] ;
132
119
// Replace leading and trailing slashes to normalize path
133
120
this . sockPath = `/${
134
- options . sockPath
135
- ? options . sockPath . replace ( / ^ \/ | \/ $ / g, '' )
121
+ this . options . sockPath
122
+ ? this . options . sockPath . replace ( / ^ \/ | \/ $ / g, '' )
136
123
: 'sockjs-node'
137
124
} `;
138
125
@@ -146,28 +133,33 @@ class Server {
146
133
this . setupDevMiddleware ( ) ;
147
134
148
135
// set express routes
149
- routes ( this . app , this . middleware , options ) ;
136
+ routes ( this . app , this . middleware , this . options ) ;
150
137
151
138
// Keep track of websocket proxies for external websocket upgrade.
152
139
this . websocketProxies = [ ] ;
153
140
154
141
this . setupFeatures ( ) ;
155
142
156
- if ( options . https ) {
143
+ // if the user enables http2, we can safely enable https
144
+ if ( this . options . http2 && ! this . options . https ) {
145
+ this . options . https = true ;
146
+ }
147
+
148
+ if ( this . options . https ) {
157
149
// for keep supporting CLI parameters
158
- if ( typeof options . https === 'boolean' ) {
159
- options . https = {
160
- ca : options . ca ,
161
- pfx : options . pfx ,
162
- key : options . key ,
163
- cert : options . cert ,
164
- passphrase : options . pfxPassphrase ,
165
- requestCert : options . requestCert || false ,
150
+ if ( typeof this . options . https === 'boolean' ) {
151
+ this . options . https = {
152
+ ca : this . options . ca ,
153
+ pfx : this . options . pfx ,
154
+ key : this . options . key ,
155
+ cert : this . options . cert ,
156
+ passphrase : this . options . pfxPassphrase ,
157
+ requestCert : this . options . requestCert || false ,
166
158
} ;
167
159
}
168
160
169
161
for ( const property of [ 'ca' , 'pfx' , 'key' , 'cert' ] ) {
170
- const value = options . https [ property ] ;
162
+ const value = this . options . https [ property ] ;
171
163
const isBuffer = value instanceof Buffer ;
172
164
173
165
if ( value && ! isBuffer ) {
@@ -181,73 +173,38 @@ class Server {
181
173
182
174
if ( stats ) {
183
175
// It is file
184
- options . https [ property ] = fs . readFileSync ( path . resolve ( value ) ) ;
176
+ this . options . https [ property ] = fs . readFileSync ( path . resolve ( value ) ) ;
185
177
} else {
186
- options . https [ property ] = value ;
178
+ this . options . https [ property ] = value ;
187
179
}
188
180
}
189
181
}
190
182
191
183
let fakeCert ;
192
184
193
- if ( ! options . https . key || ! options . https . cert ) {
194
- // Use a self-signed certificate if no certificate was configured.
195
- // Cycle certs every 24 hours
196
- const certPath = path . join ( __dirname , '../ssl/server.pem' ) ;
197
-
198
- let certExists = fs . existsSync ( certPath ) ;
199
-
200
- if ( certExists ) {
201
- const certTtl = 1000 * 60 * 60 * 24 ;
202
- const certStat = fs . statSync ( certPath ) ;
203
-
204
- const now = new Date ( ) ;
205
-
206
- // cert is more than 30 days old, kill it with fire
207
- if ( ( now - certStat . ctime ) / certTtl > 30 ) {
208
- this . log . info (
209
- 'SSL Certificate is more than 30 days old. Removing.'
210
- ) ;
211
-
212
- del . sync ( [ certPath ] , { force : true } ) ;
213
-
214
- certExists = false ;
215
- }
216
- }
217
-
218
- if ( ! certExists ) {
219
- this . log . info ( 'Generating SSL Certificate' ) ;
220
-
221
- const attrs = [ { name : 'commonName' , value : 'localhost' } ] ;
222
- const pems = createCertificate ( attrs ) ;
223
-
224
- fs . writeFileSync ( certPath , pems . private + pems . cert , {
225
- encoding : 'utf8' ,
226
- } ) ;
227
- }
228
-
229
- fakeCert = fs . readFileSync ( certPath ) ;
185
+ if ( ! this . options . https . key || ! this . options . https . cert ) {
186
+ fakeCert = getCertificate ( this . log ) ;
230
187
}
231
188
232
- options . https . key = options . https . key || fakeCert ;
233
- options . https . cert = options . https . cert || fakeCert ;
189
+ this . options . https . key = this . options . https . key || fakeCert ;
190
+ this . options . https . cert = this . options . https . cert || fakeCert ;
234
191
235
192
// Only prevent HTTP/2 if http2 is explicitly set to false
236
- const isHttp2 = options . http2 !== false ;
193
+ const isHttp2 = this . options . http2 !== false ;
237
194
238
195
// note that options.spdy never existed. The user was able
239
196
// to set options.https.spdy before, though it was not in the
240
197
// docs. Keep options.https.spdy if the user sets it for
241
198
// backwards compatability, but log a deprecation warning.
242
- if ( options . https . spdy ) {
199
+ if ( this . options . https . spdy ) {
243
200
// for backwards compatability: if options.https.spdy was passed in before,
244
201
// it was not altered in any way
245
202
this . log . warn (
246
203
'Providing custom spdy server options is deprecated and will be removed in the next major version.'
247
204
) ;
248
205
} else {
249
206
// if the normal https server gets this option, it will not affect it.
250
- options . https . spdy = {
207
+ this . options . https . spdy = {
251
208
protocols : [ 'h2' , 'http/1.1' ] ,
252
209
} ;
253
210
}
@@ -262,21 +219,21 @@ class Server {
262
219
// - https://github.com/webpack/webpack-dev-server/issues/1449
263
220
// - https://github.com/expressjs/express/issues/3388
264
221
if ( semver . gte ( process . version , '10.0.0' ) || ! isHttp2 ) {
265
- if ( options . http2 ) {
222
+ if ( this . options . http2 ) {
266
223
// the user explicitly requested http2 but is not getting it because
267
224
// of the node version.
268
225
this . log . warn (
269
226
'HTTP/2 is currently unsupported for Node 10.0.0 and above, but will be supported once Express supports it'
270
227
) ;
271
228
}
272
- this . listeningApp = https . createServer ( options . https , this . app ) ;
229
+ this . listeningApp = https . createServer ( this . options . https , this . app ) ;
273
230
} else {
274
231
/* eslint-disable global-require */
275
232
// The relevant issues are:
276
233
// https://github.com/spdy-http2/node-spdy/issues/350
277
234
// https://github.com/webpack/webpack-dev-server/issues/1592
278
235
this . listeningApp = require ( 'spdy' ) . createServer (
279
- options . https ,
236
+ this . options . https ,
280
237
this . app
281
238
) ;
282
239
/* eslint-enable global-require */
@@ -941,7 +898,7 @@ class Server {
941
898
? this . watchOptions . poll
942
899
: undefined ;
943
900
944
- const options = {
901
+ const watchOptions = {
945
902
ignoreInitial : true ,
946
903
persistent : true ,
947
904
followSymlinks : false ,
@@ -953,7 +910,7 @@ class Server {
953
910
interval,
954
911
} ;
955
912
956
- const watcher = chokidar . watch ( watchPath , options ) ;
913
+ const watcher = chokidar . watch ( watchPath , watchOptions ) ;
957
914
958
915
watcher . on ( 'change' , ( ) => {
959
916
this . sockWrite ( this . sockets , 'content-changed' ) ;
0 commit comments