@@ -444,14 +444,125 @@ class Server {
444
444
445
445
const compilerOptions = this . getCompilerOptions ( ) ;
446
446
// TODO remove `{}` after drop webpack v4 support
447
- const watchOptions = compilerOptions . watchOptions || { } ;
448
- const defaultOptionsForStatic = {
449
- directory : path . join ( process . cwd ( ) , "public" ) ,
450
- staticOptions : { } ,
451
- publicPath : [ "/" ] ,
452
- serveIndex : { icons : true } ,
453
- // Respect options from compiler watchOptions
454
- watch : watchOptions ,
447
+ const compilerWatchOptions = compilerOptions . watchOptions || { } ;
448
+ const getWatchOptions = ( watchOptions = { } ) => {
449
+ const getPolling = ( ) => {
450
+ if ( typeof watchOptions . usePolling !== "undefined" ) {
451
+ return watchOptions . usePolling ;
452
+ }
453
+
454
+ if ( typeof watchOptions . poll !== "undefined" ) {
455
+ return Boolean ( watchOptions . poll ) ;
456
+ }
457
+
458
+ if ( typeof compilerWatchOptions . poll !== "undefined" ) {
459
+ return Boolean ( compilerWatchOptions . poll ) ;
460
+ }
461
+
462
+ return false ;
463
+ } ;
464
+ const getInterval = ( ) => {
465
+ if ( typeof watchOptions . interval !== "undefined" ) {
466
+ return watchOptions . interval ;
467
+ }
468
+
469
+ if ( typeof watchOptions . poll === "number" ) {
470
+ return watchOptions . poll ;
471
+ }
472
+
473
+ if ( typeof compilerWatchOptions . poll === "number" ) {
474
+ return compilerWatchOptions . poll ;
475
+ }
476
+ } ;
477
+
478
+ const usePolling = getPolling ( ) ;
479
+ const interval = getInterval ( ) ;
480
+ const { poll, ...rest } = watchOptions ;
481
+
482
+ return {
483
+ ignoreInitial : true ,
484
+ persistent : true ,
485
+ followSymlinks : false ,
486
+ atomic : false ,
487
+ alwaysStat : true ,
488
+ ignorePermissionErrors : true ,
489
+ // Respect options from compiler watchOptions
490
+ usePolling,
491
+ interval,
492
+ ignored : watchOptions . ignored ,
493
+ // TODO: we respect these options for all watch options and allow developers to pass them to chokidar, but chokidar doesn't have these options maybe we need revisit that in future
494
+ ...rest ,
495
+ } ;
496
+ } ;
497
+ const getStaticItem = ( optionsForStatic ) => {
498
+ const getDefaultStaticOptions = ( ) => {
499
+ return {
500
+ directory : path . join ( process . cwd ( ) , "public" ) ,
501
+ staticOptions : { } ,
502
+ publicPath : [ "/" ] ,
503
+ serveIndex : { icons : true } ,
504
+ watch : getWatchOptions ( ) ,
505
+ } ;
506
+ } ;
507
+
508
+ let item ;
509
+
510
+ if ( typeof optionsForStatic === "undefined" ) {
511
+ item = getDefaultStaticOptions ( ) ;
512
+ } else if ( typeof optionsForStatic === "string" ) {
513
+ item = {
514
+ ...getDefaultStaticOptions ( ) ,
515
+ directory : optionsForStatic ,
516
+ } ;
517
+ } else {
518
+ const def = getDefaultStaticOptions ( ) ;
519
+
520
+ item = {
521
+ directory :
522
+ typeof optionsForStatic . directory !== "undefined"
523
+ ? optionsForStatic . directory
524
+ : def . directory ,
525
+ // TODO: do merge in the next major release
526
+ staticOptions :
527
+ typeof optionsForStatic . staticOptions !== "undefined"
528
+ ? optionsForStatic . staticOptions
529
+ : def . staticOptions ,
530
+ publicPath :
531
+ typeof optionsForStatic . publicPath !== "undefined"
532
+ ? optionsForStatic . publicPath
533
+ : def . publicPath ,
534
+ // TODO: do merge in the next major release
535
+ serveIndex :
536
+ // eslint-disable-next-line no-nested-ternary
537
+ typeof optionsForStatic . serveIndex !== "undefined"
538
+ ? typeof optionsForStatic . serveIndex === "boolean" &&
539
+ optionsForStatic . serveIndex
540
+ ? def . serveIndex
541
+ : optionsForStatic . serveIndex
542
+ : def . serveIndex ,
543
+ watch :
544
+ // eslint-disable-next-line no-nested-ternary
545
+ typeof optionsForStatic . watch !== "undefined"
546
+ ? // eslint-disable-next-line no-nested-ternary
547
+ typeof optionsForStatic . watch === "boolean"
548
+ ? optionsForStatic . watch
549
+ ? def . watch
550
+ : false
551
+ : getWatchOptions ( optionsForStatic . watch )
552
+ : def . watch ,
553
+ } ;
554
+ }
555
+
556
+ if ( Server . isAbsoluteURL ( item . directory ) ) {
557
+ throw new Error ( "Using a URL as static.directory is not supported" ) ;
558
+ }
559
+
560
+ // ensure that publicPath is an array
561
+ if ( typeof item . publicPath === "string" ) {
562
+ item . publicPath = [ item . publicPath ] ;
563
+ }
564
+
565
+ return item ;
455
566
} ;
456
567
457
568
if ( typeof options . allowedHosts === "undefined" ) {
@@ -921,50 +1032,27 @@ class Server {
921
1032
}
922
1033
923
1034
if ( typeof options . static === "undefined" ) {
924
- options . static = [ defaultOptionsForStatic ] ;
1035
+ options . static = [ getStaticItem ( ) ] ;
925
1036
} else if ( typeof options . static === "boolean" ) {
926
- options . static = options . static ? [ defaultOptionsForStatic ] : false ;
1037
+ options . static = options . static ? [ getStaticItem ( ) ] : false ;
927
1038
} else if ( typeof options . static === "string" ) {
928
- options . static = [
929
- { ...defaultOptionsForStatic , directory : options . static } ,
930
- ] ;
1039
+ options . static = [ getStaticItem ( options . static ) ] ;
931
1040
} else if ( Array . isArray ( options . static ) ) {
932
1041
options . static = options . static . map ( ( item ) => {
933
1042
if ( typeof item === "string" ) {
934
- return { ... defaultOptionsForStatic , directory : item } ;
1043
+ return getStaticItem ( item ) ;
935
1044
}
936
1045
937
- return { ... defaultOptionsForStatic , ... item } ;
1046
+ return getStaticItem ( item ) ;
938
1047
} ) ;
939
1048
} else {
940
- options . static = [ { ...defaultOptionsForStatic , ...options . static } ] ;
941
- }
942
-
943
- if ( options . static ) {
944
- options . static . forEach ( ( staticOption ) => {
945
- if ( Server . isAbsoluteURL ( staticOption . directory ) ) {
946
- throw new Error ( "Using a URL as static.directory is not supported" ) ;
947
- }
948
-
949
- // ensure that publicPath is an array
950
- if ( typeof staticOption . publicPath === "string" ) {
951
- staticOption . publicPath = [ staticOption . publicPath ] ;
952
- }
953
-
954
- // ensure that watch is an object if true
955
- if ( staticOption . watch === true ) {
956
- staticOption . watch = defaultOptionsForStatic . watch ;
957
- }
958
-
959
- // ensure that serveIndex is an object if true
960
- if ( staticOption . serveIndex === true ) {
961
- staticOption . serveIndex = defaultOptionsForStatic . serveIndex ;
962
- }
963
- } ) ;
1049
+ options . static = [ getStaticItem ( options . static ) ] ;
964
1050
}
965
1051
966
1052
if ( typeof options . watchFiles === "string" ) {
967
- options . watchFiles = [ { paths : options . watchFiles , options : { } } ] ;
1053
+ options . watchFiles = [
1054
+ { paths : options . watchFiles , options : getWatchOptions ( ) } ,
1055
+ ] ;
968
1056
} else if (
969
1057
typeof options . watchFiles === "object" &&
970
1058
options . watchFiles !== null &&
@@ -973,16 +1061,19 @@ class Server {
973
1061
options . watchFiles = [
974
1062
{
975
1063
paths : options . watchFiles . paths ,
976
- options : options . watchFiles . options || { } ,
1064
+ options : getWatchOptions ( options . watchFiles . options || { } ) ,
977
1065
} ,
978
1066
] ;
979
1067
} else if ( Array . isArray ( options . watchFiles ) ) {
980
1068
options . watchFiles = options . watchFiles . map ( ( item ) => {
981
1069
if ( typeof item === "string" ) {
982
- return { paths : item , options : { } } ;
1070
+ return { paths : item , options : getWatchOptions ( ) } ;
983
1071
}
984
1072
985
- return { paths : item . paths , options : item . options || { } } ;
1073
+ return {
1074
+ paths : item . paths ,
1075
+ options : getWatchOptions ( item . options || { } ) ,
1076
+ } ;
986
1077
} ) ;
987
1078
} else {
988
1079
options . watchFiles = [ ] ;
@@ -2124,36 +2215,8 @@ class Server {
2124
2215
}
2125
2216
2126
2217
watchFiles ( watchPath , watchOptions ) {
2127
- // duplicate the same massaging of options that watchpack performs
2128
- // https://github.com/webpack/watchpack/blob/master/lib/DirectoryWatcher.js#L49
2129
- // this isn't an elegant solution, but we'll improve it in the future
2130
- const usePolling =
2131
- typeof watchOptions . usePolling !== "undefined"
2132
- ? watchOptions . usePolling
2133
- : Boolean ( watchOptions . poll ) ;
2134
- const interval =
2135
- // eslint-disable-next-line no-nested-ternary
2136
- typeof watchOptions . interval !== "undefined"
2137
- ? watchOptions . interval
2138
- : typeof watchOptions . poll === "number"
2139
- ? watchOptions . poll
2140
- : // eslint-disable-next-line no-undefined
2141
- undefined ;
2142
-
2143
- const finalWatchOptions = {
2144
- ignoreInitial : true ,
2145
- persistent : true ,
2146
- followSymlinks : false ,
2147
- atomic : false ,
2148
- alwaysStat : true ,
2149
- ignorePermissionErrors : true ,
2150
- ignored : watchOptions . ignored ,
2151
- usePolling,
2152
- interval,
2153
- } ;
2154
-
2155
2218
const chokidar = require ( "chokidar" ) ;
2156
- const watcher = chokidar . watch ( watchPath , finalWatchOptions ) ;
2219
+ const watcher = chokidar . watch ( watchPath , watchOptions ) ;
2157
2220
2158
2221
// disabling refreshing on changing the content
2159
2222
if ( this . options . liveReload ) {
0 commit comments