This article shows how HMR, or Hot Module Replacement can be used together with Angular and Webpack.
Code: VS2017 angular 4.x
Blogs in this series:
- ASP.NET Core, Angular with Webpack and Visual Studio
- Building production ready Angular apps with Visual Studio and ASP.NET Core
- Angular Lazy Loading with Webpack 2
- Hot Module Replacement with Angular and Webpack
2017.07.15: Updated to angular 4.3.0 and Webpack 3
See here for full history:
https://github.com/damienbod/AngularWebpackVisualStudio/blob/master/CHANGELOG.md
package.json npm file
The webpack-dev-server from Kees Kluskens is added to the devDependencies in the npm package.json file. The webpack-dev-server package implements and supports the HMR feature.
"devDependencies": { ... "webpack": "^3.2.0", "webpack-dev-server": "^2.5.1", },
In the scripts section of the package.json, the start command is configured to start the dotnet server and also the webpack-dev-server with the –hot and the –inline parameters.
See the webpack-dev-server documentation for more information about the possible parameters.
The dotnet server is only required because this demo application uses a Web API service implemented in ASP.NET Core.
"start": "concurrently \"webpack-dev-server --hot --inline --port 8080\" \"dotnet run\" "
webpack dev configuration
The devServer is added to the module.exports in the webpack.dev.js. This configures the webpack-dev-server as required. The webpack-dev-server configuration can be set here as well as the command line options, so you as a developer can decide which is better for you.
devServer: { historyApiFallback: true, contentBase: path.join(__dirname, '/wwwroot/'), watchOptions: { aggregateTimeout: 300, poll: 1000 } },
The output in the module.exports also needs to be configured correctly for the webpack-dev-server to work correctly. If the ‘./’ path is used in the path option of the output section, the webpack-dev-server will not start.
output: { path: __dirname + '/wwwroot/', filename: 'dist/[name].bundle.js', chunkFilename: 'dist/[id].chunk.js', publicPath: '/' },
The module should be declared and the module.hot needs to be added the the main.ts.
// Entry point for JiT compilation. declare var System: any; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; // Enables Hot Module Replacement. declare var module: any; if (module.hot) { module.hot.accept(); } platformBrowserDynamic().bootstrapModule(AppModule);
Running the application
Build the application using the webpack dev build. This can be done in the command line. Before building, you need to install all the npm packages using npm install.
$ npm run build-dev
The npm script build-dev is defined in the package.json file and uses the webpack-dev script which does a development build.
"build-dev": "npm run webpack-dev", "webpack-dev": "set NODE_ENV=development && webpack",
Now the server can be started using the start script.
$ npm start
The application is now running on localhost with port 8080 as defined.
If for example, the color is changed in the app.scss, the bundles will be reloaded in the browser without refreshing.
Links
https://webpack.js.org/concepts/hot-module-replacement/
https://webpack.js.org/configuration/dev-server/#devserver
https://github.com/webpack/webpack-dev-server
https://www.sitepoint.com/beginners-guide-to-webpack-2-and-module-bundling/
[…] Réaliser du Hot Module Replacement avec Angular et Webpack. […]
This is very useful tutorial I think.
Thanks for sharing
How does if (module.hot) ever get run? It’s just sitting there in the class. (E.g. Not in constructor or event handler). Also how do I know the whole page isn’t reloaded? If you type in the text box before editing the file is the text retained?
How to configure same thing in MVC project?
Adding the HMR (module.hot) code to main.ts fixed my issue. Strangely, HMR always worked for me in the past without this code. How long has module.hot been required with Angular? I recently upgraded to Angular 5, so perhaps that’s related? Thank you!