Hot Reload (Webpack)

The highest impact on your application’s bootstrapping process has a TypeScript compilation. But the question is, do we have to recompile a whole project each time when change occurs? Not at all. That’s why webpack HMR (Hot-Module Replacement) significantly decreases an amount of time necessary to instantiate your application.

warning Warning Note that webpack won’t automatically copy your assets (e.g. graphql files) to the dist folder. Similary, webpack is not compatible with glob static paths (e.g. entities property in TypeOrmModule).

With CLI

If you are using the Nest CLI, the configuration process is pretty straightforward. The CLI wraps webpack, which allows use the HotModuleReplacementPlugin.

Installation

First install the required package:

  1. $ npm i --save-dev webpack-node-externals

Configuration

Once the installation is complete, create a webpack.config.js file in the root directory of your application.

  1. const webpack = require('webpack');
  2. const nodeExternals = require('webpack-node-externals');
  3. module.exports = function(options) {
  4. return {
  5. ...options,
  6. entry: ['webpack/hot/poll?100', './src/main.ts'],
  7. watch: true,
  8. externals: [
  9. nodeExternals({
  10. whitelist: ['webpack/hot/poll?100'],
  11. }),
  12. ],
  13. plugins: [...options.plugins, new webpack.HotModuleReplacementPlugin()],
  14. };
  15. }

This function takes the original object containing the default webpack configuration and returns a modified one with an applied HotModuleReplacementPlugin plugin.

Hot-Module Replacement

In order to enable HMR, open the application entry file (main.ts) and add several webpack-related instructions, as shown below:

  1. declare const module: any;
  2. async function bootstrap() {
  3. const app = await NestFactory.create(AppModule);
  4. await app.listen(3000);
  5. if (module.hot) {
  6. module.hot.accept();
  7. module.hot.dispose(() => app.close());
  8. }
  9. }
  10. bootstrap();

To simplify the execution process, add two scripts to your package.json file.

  1. "build": "nest build --watch --webpack"
  2. "start": "node dist/main",

Now simply open your command line and run the following command:

  1. $ npm run build

Once webpack has started watching files, run the following command in a separate command line window:

  1. $ npm run start

Without CLI

If you are not using the Nest CLI, the configuration will be slightly more complex (will require more manual steps).

Installation

First install the required packages:

  1. $ npm i --save-dev webpack webpack-cli webpack-node-externals ts-loader

Configuration

Once the installation is complete, create a webpack.config.js file in the root directory of your application.

  1. const webpack = require('webpack');
  2. const path = require('path');
  3. const nodeExternals = require('webpack-node-externals');
  4. module.exports = {
  5. entry: ['webpack/hot/poll?100', './src/main.ts'],
  6. watch: true,
  7. target: 'node',
  8. externals: [
  9. nodeExternals({
  10. whitelist: ['webpack/hot/poll?100'],
  11. }),
  12. ],
  13. module: {
  14. rules: [
  15. {
  16. test: /.tsx?$/,
  17. use: 'ts-loader',
  18. exclude: /node_modules/,
  19. },
  20. ],
  21. },
  22. mode: 'development',
  23. resolve: {
  24. extensions: ['.tsx', '.ts', '.js'],
  25. },
  26. plugins: [new webpack.HotModuleReplacementPlugin()],
  27. output: {
  28. path: path.join(__dirname, 'dist'),
  29. filename: 'server.js',
  30. },
  31. };

This configuration tells webpack few essential things about our application. Where sits an entry file, which directory should be used to hold compiled files, and also, what kind of loader we want to use in order to compile source files. Basically, you shouldn’t worry to much, you don’t need to understand the content of this file at all.

Hot-Module Replacement

In order to enable HMR, we have to open the application entry file (main.ts) and add a few webpack-related instructions.

  1. declare const module: any;
  2. async function bootstrap() {
  3. const app = await NestFactory.create(AppModule);
  4. await app.listen(3000);
  5. if (module.hot) {
  6. module.hot.accept();
  7. module.hot.dispose(() => app.close());
  8. }
  9. }
  10. bootstrap();

To simplify the execution process, add two scripts to your package.json file.

  1. "webpack": "webpack --config webpack.config.js"
  2. "start": "node dist/server",

Now simply open your command line and run the following command:

  1. $ npm run webpack

Once webpack has started watching files, run the following command in a separate command line window:

  1. $ npm run start

A working example is available here.