@@ -18,7 +18,6 @@ const webpackDevMiddleware = require('webpack-dev-middleware');
18
18
const getFilenameFromUrl = require ( 'webpack-dev-middleware/dist/utils/getFilenameFromUrl' )
19
19
. default ;
20
20
const validateOptions = require ( 'schema-utils' ) ;
21
- const isAbsoluteUrl = require ( 'is-absolute-url' ) ;
22
21
const normalizeOptions = require ( './utils/normalizeOptions' ) ;
23
22
const updateCompiler = require ( './utils/updateCompiler' ) ;
24
23
const getCertificate = require ( './utils/getCertificate' ) ;
@@ -304,112 +303,43 @@ class Server {
304
303
}
305
304
306
305
setupStaticFeature ( ) {
307
- const contentBase = this . options . contentBase ;
308
- const contentBasePublicPath = this . options . contentBasePublicPath ;
309
-
310
- if ( Array . isArray ( contentBase ) ) {
311
- contentBase . forEach ( ( item , index ) => {
312
- let publicPath = contentBasePublicPath ;
313
-
314
- if (
315
- Array . isArray ( contentBasePublicPath ) &&
316
- contentBasePublicPath [ index ]
317
- ) {
318
- publicPath = contentBasePublicPath [ index ] || contentBasePublicPath [ 0 ] ;
319
- }
320
-
321
- this . app . use ( publicPath , express . static ( item ) ) ;
322
- } ) ;
323
- } else if ( isAbsoluteUrl ( String ( contentBase ) ) ) {
324
- this . logger . warn (
325
- 'Using a URL as contentBase is deprecated and will be removed in the next major version. Please use the proxy option instead.'
326
- ) ;
327
-
328
- this . logger . warn (
329
- 'proxy: {\n\t"*": "<your current contentBase configuration>"\n}'
330
- ) ;
331
-
332
- // Redirect every request to contentBase
333
- this . app . get ( '*' , ( req , res ) => {
334
- res . writeHead ( 302 , {
335
- Location : contentBase + req . path + ( req . _parsedUrl . search || '' ) ,
336
- } ) ;
337
-
338
- res . end ( ) ;
339
- } ) ;
340
- } else if ( typeof contentBase === 'number' ) {
341
- this . logger . warn (
342
- 'Using a number as contentBase is deprecated and will be removed in the next major version. Please use the proxy option instead.'
343
- ) ;
344
-
345
- this . logger . warn (
346
- 'proxy: {\n\t"*": "//localhost:<your current contentBase configuration>"\n}'
347
- ) ;
348
-
349
- // Redirect every request to the port contentBase
350
- this . app . get ( '*' , ( req , res ) => {
351
- res . writeHead ( 302 , {
352
- Location : `//localhost:${ contentBase } ${ req . path } ${
353
- req . _parsedUrl . search || ''
354
- } `,
355
- } ) ;
356
-
357
- res . end ( ) ;
306
+ this . options . static . forEach ( ( staticOption ) => {
307
+ staticOption . publicPath . forEach ( ( publicPath ) => {
308
+ this . app . use (
309
+ publicPath ,
310
+ express . static ( staticOption . directory , staticOption . staticOptions )
311
+ ) ;
358
312
} ) ;
359
- } else {
360
- // route content request
361
- this . app . use (
362
- contentBasePublicPath ,
363
- express . static ( contentBase , this . options . staticOptions )
364
- ) ;
365
- }
313
+ } ) ;
366
314
}
367
315
368
- setupServeIndexFeature ( ) {
369
- const contentBase = this . options . contentBase ;
370
- const contentBasePublicPath = this . options . contentBasePublicPath ;
371
-
372
- if ( Array . isArray ( contentBase ) ) {
373
- contentBase . forEach ( ( item ) => {
374
- this . app . use ( contentBasePublicPath , ( req , res , next ) => {
375
- // serve-index doesn't fallthrough non-get/head request to next middleware
376
- if ( req . method !== 'GET' && req . method !== 'HEAD' ) {
377
- return next ( ) ;
378
- }
316
+ setupStaticServeIndexFeature ( ) {
317
+ this . options . static . forEach ( ( staticOption ) => {
318
+ staticOption . publicPath . forEach ( ( publicPath ) => {
319
+ if ( staticOption . serveIndex ) {
320
+ this . app . use ( publicPath , ( req , res , next ) => {
321
+ // serve-index doesn't fallthrough non-get/head request to next middleware
322
+ if ( req . method !== 'GET' && req . method !== 'HEAD' ) {
323
+ return next ( ) ;
324
+ }
379
325
380
- serveIndex ( item , { icons : true } ) ( req , res , next ) ;
381
- } ) ;
382
- } ) ;
383
- } else if (
384
- typeof contentBase !== 'number' &&
385
- ! isAbsoluteUrl ( String ( contentBase ) )
386
- ) {
387
- this . app . use ( contentBasePublicPath , ( req , res , next ) => {
388
- // serve-index doesn't fallthrough non-get/head request to next middleware
389
- if ( req . method !== 'GET' && req . method !== 'HEAD' ) {
390
- return next ( ) ;
326
+ serveIndex ( staticOption . directory , staticOption . serveIndex ) (
327
+ req ,
328
+ res ,
329
+ next
330
+ ) ;
331
+ } ) ;
391
332
}
392
-
393
- serveIndex ( contentBase , { icons : true } ) ( req , res , next ) ;
394
333
} ) ;
395
- }
334
+ } ) ;
396
335
}
397
336
398
- setupWatchStaticFeature ( ) {
399
- const contentBase = this . options . contentBase ;
400
-
401
- if ( isAbsoluteUrl ( String ( contentBase ) ) || typeof contentBase === 'number' ) {
402
- throw new Error ( 'Watching remote files is not supported.' ) ;
403
- } else if ( Array . isArray ( contentBase ) ) {
404
- contentBase . forEach ( ( item ) => {
405
- if ( isAbsoluteUrl ( String ( item ) ) || typeof item === 'number' ) {
406
- throw new Error ( 'Watching remote files is not supported.' ) ;
407
- }
408
- this . _watch ( item ) ;
409
- } ) ;
410
- } else {
411
- this . _watch ( contentBase ) ;
412
- }
337
+ setupStaticWatchFeature ( ) {
338
+ this . options . static . forEach ( ( staticOption ) => {
339
+ if ( staticOption . watch ) {
340
+ this . watchFiles ( staticOption . directory , staticOption . watch ) ;
341
+ }
342
+ } ) ;
413
343
}
414
344
415
345
setupOnBeforeSetupMiddlewareFeature ( ) {
@@ -449,17 +379,14 @@ class Server {
449
379
this . setupHistoryApiFallbackFeature ( ) ;
450
380
}
451
381
} ,
452
- // Todo rename to `static` in future major release
453
- contentBaseFiles : ( ) => {
382
+ static : ( ) => {
454
383
this . setupStaticFeature ( ) ;
455
384
} ,
456
- // Todo rename to `serveIndex` in future major release
457
- contentBaseIndex : ( ) => {
458
- this . setupServeIndexFeature ( ) ;
385
+ staticServeIndex : ( ) => {
386
+ this . setupStaticServeIndexFeature ( ) ;
459
387
} ,
460
- // Todo rename to `watchStatic` in future major release
461
- watchContentBase : ( ) => {
462
- this . setupWatchStaticFeature ( ) ;
388
+ staticWatch : ( ) => {
389
+ this . setupStaticWatchFeature ( ) ;
463
390
} ,
464
391
onBeforeSetupMiddleware : ( ) => {
465
392
if ( typeof this . options . onBeforeSetupMiddleware === 'function' ) {
@@ -501,24 +428,20 @@ class Server {
501
428
runnableFeatures . push ( 'proxy' , 'middleware' ) ;
502
429
}
503
430
504
- if ( this . options . contentBase !== false ) {
505
- runnableFeatures . push ( 'contentBaseFiles ' ) ;
431
+ if ( this . options . static ) {
432
+ runnableFeatures . push ( 'static ' ) ;
506
433
}
507
434
508
435
if ( this . options . historyApiFallback ) {
509
436
runnableFeatures . push ( 'historyApiFallback' , 'middleware' ) ;
510
437
511
- if ( this . options . contentBase !== false ) {
512
- runnableFeatures . push ( 'contentBaseFiles ' ) ;
438
+ if ( this . options . static ) {
439
+ runnableFeatures . push ( 'static ' ) ;
513
440
}
514
441
}
515
442
516
- if ( this . options . contentBase && this . options . serveIndex ) {
517
- runnableFeatures . push ( 'contentBaseIndex' ) ;
518
- }
519
-
520
- if ( this . options . watchContentBase ) {
521
- runnableFeatures . push ( 'watchContentBase' ) ;
443
+ if ( this . options . static ) {
444
+ runnableFeatures . push ( 'staticServeIndex' , 'staticWatch' ) ;
522
445
}
523
446
524
447
runnableFeatures . push ( 'magicHtml' ) ;
@@ -903,31 +826,31 @@ class Server {
903
826
}
904
827
}
905
828
906
- _watch ( watchPath ) {
829
+ watchFiles ( watchPath , watchOptions ) {
907
830
// duplicate the same massaging of options that watchpack performs
908
831
// https://github.com/webpack/watchpack/blob/master/lib/DirectoryWatcher.js#L49
909
832
// this isn't an elegant solution, but we'll improve it in the future
910
833
// eslint-disable-next-line no-undefined
911
- const usePolling = this . options . watchOptions . poll ? true : undefined ;
834
+ const usePolling = watchOptions . poll ? true : undefined ;
912
835
const interval =
913
- typeof this . options . watchOptions . poll === 'number'
914
- ? this . options . watchOptions . poll
836
+ typeof watchOptions . poll === 'number'
837
+ ? watchOptions . poll
915
838
: // eslint-disable-next-line no-undefined
916
839
undefined ;
917
840
918
- const watchOptions = {
841
+ const finalWatchOptions = {
919
842
ignoreInitial : true ,
920
843
persistent : true ,
921
844
followSymlinks : false ,
922
845
atomic : false ,
923
846
alwaysStat : true ,
924
847
ignorePermissionErrors : true ,
925
- ignored : this . options . watchOptions . ignored ,
848
+ ignored : watchOptions . ignored ,
926
849
usePolling,
927
850
interval,
928
851
} ;
929
852
930
- const watcher = chokidar . watch ( watchPath , watchOptions ) ;
853
+ const watcher = chokidar . watch ( watchPath , finalWatchOptions ) ;
931
854
// disabling refreshing on changing the content
932
855
if ( this . options . liveReload ) {
933
856
watcher . on ( 'change' , ( ) => {
0 commit comments