@@ -444,14 +444,125 @@ class Server {
444444
445445 const compilerOptions = this . getCompilerOptions ( ) ;
446446 // 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 ;
455566 } ;
456567
457568 if ( typeof options . allowedHosts === "undefined" ) {
@@ -921,50 +1032,27 @@ class Server {
9211032 }
9221033
9231034 if ( typeof options . static === "undefined" ) {
924- options . static = [ defaultOptionsForStatic ] ;
1035+ options . static = [ getStaticItem ( ) ] ;
9251036 } else if ( typeof options . static === "boolean" ) {
926- options . static = options . static ? [ defaultOptionsForStatic ] : false ;
1037+ options . static = options . static ? [ getStaticItem ( ) ] : false ;
9271038 } else if ( typeof options . static === "string" ) {
928- options . static = [
929- { ...defaultOptionsForStatic , directory : options . static } ,
930- ] ;
1039+ options . static = [ getStaticItem ( options . static ) ] ;
9311040 } else if ( Array . isArray ( options . static ) ) {
9321041 options . static = options . static . map ( ( item ) => {
9331042 if ( typeof item === "string" ) {
934- return { ... defaultOptionsForStatic , directory : item } ;
1043+ return getStaticItem ( item ) ;
9351044 }
9361045
937- return { ... defaultOptionsForStatic , ... item } ;
1046+ return getStaticItem ( item ) ;
9381047 } ) ;
9391048 } 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 ) ] ;
9641050 }
9651051
9661052 if ( typeof options . watchFiles === "string" ) {
967- options . watchFiles = [ { paths : options . watchFiles , options : { } } ] ;
1053+ options . watchFiles = [
1054+ { paths : options . watchFiles , options : getWatchOptions ( ) } ,
1055+ ] ;
9681056 } else if (
9691057 typeof options . watchFiles === "object" &&
9701058 options . watchFiles !== null &&
@@ -973,16 +1061,19 @@ class Server {
9731061 options . watchFiles = [
9741062 {
9751063 paths : options . watchFiles . paths ,
976- options : options . watchFiles . options || { } ,
1064+ options : getWatchOptions ( options . watchFiles . options || { } ) ,
9771065 } ,
9781066 ] ;
9791067 } else if ( Array . isArray ( options . watchFiles ) ) {
9801068 options . watchFiles = options . watchFiles . map ( ( item ) => {
9811069 if ( typeof item === "string" ) {
982- return { paths : item , options : { } } ;
1070+ return { paths : item , options : getWatchOptions ( ) } ;
9831071 }
9841072
985- return { paths : item . paths , options : item . options || { } } ;
1073+ return {
1074+ paths : item . paths ,
1075+ options : getWatchOptions ( item . options || { } ) ,
1076+ } ;
9861077 } ) ;
9871078 } else {
9881079 options . watchFiles = [ ] ;
@@ -2124,36 +2215,8 @@ class Server {
21242215 }
21252216
21262217 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-
21552218 const chokidar = require ( "chokidar" ) ;
2156- const watcher = chokidar . watch ( watchPath , finalWatchOptions ) ;
2219+ const watcher = chokidar . watch ( watchPath , watchOptions ) ;
21572220
21582221 // disabling refreshing on changing the content
21592222 if ( this . options . liveReload ) {
0 commit comments