@@ -43,7 +43,7 @@ function attachWebpackDevMiddleware(app: any, webpackConfig: webpack.Configurati
4343 }
4444 } ) ;
4545
46- webpackConfig . plugins = webpackConfig . plugins || [ ] ;
46+ webpackConfig . plugins = [ ] . concat ( webpackConfig . plugins || [ ] ) ; // Be sure not to mutate the original array, as it might be shared
4747 webpackConfig . plugins . push (
4848 new webpack . HotModuleReplacementPlugin ( )
4949 ) ;
@@ -79,6 +79,13 @@ function attachWebpackDevMiddleware(app: any, webpackConfig: webpack.Configurati
7979 }
8080}
8181
82+ function beginWebpackWatcher ( webpackConfig : webpack . Configuration ) {
83+ const compiler = webpack ( webpackConfig ) ;
84+ compiler . watch ( { /* watchOptions */ } , ( err , stats ) => {
85+ // The default error reporter is fine for now, but could be customized here in the future if desired
86+ } ) ;
87+ }
88+
8289export function createWebpackDevServer ( callback : CreateDevServerCallback , optionsJson : string ) {
8390 const options : CreateDevServerOptions = JSON . parse ( optionsJson ) ;
8491
@@ -93,15 +100,6 @@ export function createWebpackDevServer(callback: CreateDevServerCallback, option
93100 webpackConfigArray = [ webpackConfigArray as webpack . Configuration ] ;
94101 }
95102
96- // Check that at least one of the configurations specifies a publicPath. Those are the only ones we'll
97- // enable middleware for, and if there aren't any, you must be making a mistake.
98- const webpackConfigsWithPublicPath = webpackConfigArray
99- . filter ( webpackConfig => ( webpackConfig . output . publicPath || '' ) . trim ( ) !== '' ) ;
100- if ( webpackConfigsWithPublicPath . length === 0 ) {
101- callback ( 'To use the Webpack dev server, you must specify a value for \'publicPath\' on the \'output\' section of your webpack.config.' , null ) ;
102- return ;
103- }
104-
105103 const enableHotModuleReplacement = options . suppliedOptions . HotModuleReplacement ;
106104 const enableReactHotModuleReplacement = options . suppliedOptions . ReactHotModuleReplacement ;
107105 if ( enableReactHotModuleReplacement && ! enableHotModuleReplacement ) {
@@ -116,16 +114,30 @@ export function createWebpackDevServer(callback: CreateDevServerCallback, option
116114 const listener = app . listen ( suggestedHMRPortOrZero , ( ) => {
117115 try {
118116 // For each webpack config that specifies a public path, add webpack dev middleware for it
119- webpackConfigsWithPublicPath . forEach ( webpackConfig => {
120- attachWebpackDevMiddleware ( app , webpackConfig , enableHotModuleReplacement , enableReactHotModuleReplacement ) ;
117+ const normalizedPublicPaths : string [ ] = [ ] ;
118+ webpackConfigArray . forEach ( webpackConfig => {
119+ if ( webpackConfig . target === 'node' ) {
120+ // For configs that target Node, it's meaningless to set up an HTTP listener, since
121+ // Node isn't going to load those modules over HTTP anyway. It just loads them directly
122+ // from disk. So the most relevant thing we can do with such configs is just write
123+ // updated builds to disk, just like "webpack --watch".
124+ beginWebpackWatcher ( webpackConfig ) ;
125+ } else {
126+ // For configs that target browsers, we can set up an HTTP listener, and dynamically
127+ // modify the config to enable HMR etc. This just requires that we have a publicPath.
128+ const publicPath = ( webpackConfig . output . publicPath || '' ) . trim ( ) ;
129+ if ( ! publicPath ) {
130+ throw new Error ( 'To use the Webpack dev server, you must specify a value for \'publicPath\' on the \'output\' section of your webpack config (for any configuration that targets browsers)' ) ;
131+ }
132+ normalizedPublicPaths . push ( removeTrailingSlash ( publicPath ) ) ;
133+ attachWebpackDevMiddleware ( app , webpackConfig , enableHotModuleReplacement , enableReactHotModuleReplacement ) ;
134+ }
121135 } ) ;
122136
123137 // Tell the ASP.NET app what addresses we're listening on, so that it can proxy requests here
124138 callback ( null , {
125139 Port : listener . address ( ) . port ,
126- PublicPaths : webpackConfigsWithPublicPath . map ( webpackConfig =>
127- removeTrailingSlash ( getPath ( webpackConfig . output . publicPath ) )
128- )
140+ PublicPaths : normalizedPublicPaths
129141 } ) ;
130142 } catch ( ex ) {
131143 callback ( ex . stack , null ) ;
0 commit comments