nx icon indicating copy to clipboard operation
nx copied to clipboard

[feature] nest hot reload

Open yassernasc opened this issue 6 years ago • 18 comments

Expected Behavior

Out-of-box webpack hot reload on created nest apps.

Current Behavior

Needed to add webpack manually following the tutorial: https://docs.nestjs.com/techniques/hot-reload.

yassernasc avatar Oct 25 '19 03:10 yassernasc

This feature would be incredible

flogh avatar Feb 02 '20 16:02 flogh

Hi, sorry about this.

This was mislabeled as stale. We are testing ways to mark not reproducible issues as stale so that we can focus on actionable items but our initial experiment was too broad and unintentionally labeled this issue as stale.

FrozenPandaz avatar May 29 '20 19:05 FrozenPandaz

Hey, would love to see a solution for this. BTW I found this on Stackoverflow -> https://stackoverflow.com/questions/60476245/how-to-setup-webpacks-hmr-in-nestjs-project-in-nx-monorepo

Nightbr avatar Sep 19 '20 10:09 Nightbr

any updates on this?

webberwang avatar Nov 11 '20 10:11 webberwang

@yassernascimento Any way you could show how you did it manually?

rubennaatje avatar Dec 23 '20 09:12 rubennaatje

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs. If we missed this issue please reply to keep it active. Thanks for being a part of the Nx community! 🙏

github-actions[bot] avatar Mar 29 '21 15:03 github-actions[bot]

@rubennaatje didn't try yet, sorry

yassernasc avatar Mar 29 '21 15:03 yassernasc

any news?

pacexy avatar Aug 31 '21 10:08 pacexy

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs. If we missed this issue please reply to keep it active. Thanks for being a part of the Nx community! 🙏

github-actions[bot] avatar May 09 '22 00:05 github-actions[bot]

I’ve tried a few times to get this working and it’s just no go. I’m not even sure how well the feature works outside of the nest cli, does anyone have any experience?

jensbodal avatar May 13 '22 20:05 jensbodal

Unstale please

mehrad-rafigh avatar Aug 26 '22 18:08 mehrad-rafigh

please.. help

MinJungHyun avatar Oct 23 '22 02:10 MinJungHyun

Are there any updates regarding this? I am facing this same issue.

DeepaPrasanna avatar Nov 24 '22 07:11 DeepaPrasanna

Until this is added here's how to get HMR working with Nx 16.1.4 and NestJS 10.

Create a webpack.hmr.config.js file like this:

const { composePlugins, withNx } = require('@nx/webpack');
const nodeExternals = require('webpack-node-externals');
const webpack = require('webpack')

// Set true if you don't want type checking
const skipTypeChecking = false

// Nx plugins for webpack.
module.exports = composePlugins(withNx({ skipTypeChecking }), (config) => {
  // Update the webpack config as needed here.
  // e.g. `config.plugins.push(new MyPlugin())`
  return {
    ...config,
    entry: ['webpack/hot/poll?100', ...config.entry.main],
    externals: [
      nodeExternals({
        allowlist: ['webpack/hot/poll?100'],
      }),
    ],
    plugins: [
      ...config.plugins,
      new webpack.HotModuleReplacementPlugin(),
      new webpack.WatchIgnorePlugin({
        paths: [/\.js$/, /\.d\.ts$/],
      }),
    ],
  };
});

Set your project.json like this

{
  "targets": {
    "build": {
      "executor": "@nx/webpack:webpack",
      "outputs": ["{options.outputPath}"],
      "defaultConfiguration": "production",
      "options": {
        "target": "node",
        "compiler": "tsc",
        "outputPath": "dist/apps/your-nest-app",
        "main": "apps/your-nest-app/src/main.ts",
        "tsConfig": "apps/your-nest-app/tsconfig.app.json",
        "assets": [
          "apps/your-nest-app/src/assets"
        ],
        "isolatedConfig": true
      },
      "configurations": {
        "development": {
          "webpackConfig": "apps/your-nest-app/webpack.hmr.config.js"
        },
        "production": {
          "webpackConfig": "apps/your-nest-app/webpack.config.js",
          "generatePackageJson": true
        }
      }
    },
    "serve": {
      "executor": "@nx/js:node",
      "defaultConfiguration": "development",
      "watch": false,
      "options": {
        "buildTarget": "your-nest-app:build"
      },
      "configurations": {
        "development": {
          "buildTarget": "your-nest-app:build:development"
        },
        "production": {
          "buildTarget": "your-nest-app:build:production"
        }
      }
    }
  }
}

Make sure watch is set to false. Then set up your main.ts like this

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();

Now you can run nx serve your-nest-app and it will reload with HMR.

Don't upgrade past nx 16.1.4 until these issues are fixed: https://github.com/nrwl/nx/issues/17070 https://github.com/nrwl/nx/issues/17868

antischematic avatar Jul 02 '23 01:07 antischematic

@antischematic unfortunately this no longer works

nest: 10.3.2
nx: 18.0.6

And it appears those linked issues are fixed

I am currently getting this error

TypeError [ERR_INVALID_ARG_TYPE]: The "paths[1]" argument must be of type string. Received undefined
    at validateString (node:internal/validators:162:11)
    at resolve (node:path:1101:7)
    at /home/dan/dev/templi/templi/node_modules/@nx/webpack/src/plugins/nx-webpack-plugin/lib/normalize-options.js:79:59
    at Array.map (<anonymous>)
    at normalizeAssets (/home/dan/dev/templi/templi/node_modules/@nx/webpack/src/plugins/nx-webpack-plugin/lib/normalize-options.js:75:19)
    at normalizeOptions (/home/dan/dev/templi/templi/node_modules/@nx/webpack/src/executors/webpack/lib/normalize-options.js:24:76)
    at webpackExecutor (/home/dan/dev/templi/templi/node_modules/@nx/webpack/src/executors/webpack/webpack.impl.js:58:62)
    at webpackExecutor.next (<anonymous>)
    at /home/dan/dev/templi/templi/node_modules/@nx/js/src/executors/node/node.impl.js:191:44
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 'ERR_INVALID_ARG_TYPE'
}

Not sure if this belongs in a separate issue - i'm not 100% sure whats going on there

dan-cooke avatar Mar 02 '24 09:03 dan-cooke

@dan-cooke I got it to work with nest 10.3.7 and nx 18.2.1 with the following

webpack.hmr.config.js

const { composePlugins, withNx } = require('@nx/webpack');
const nodeExternals = require('webpack-node-externals');
const webpack = require('webpack')

// Set true if you don't want type checking
const skipTypeChecking = false

// Nx plugins for webpack.
module.exports = composePlugins(withNx({ skipTypeChecking }), (config) => {
  // Update the webpack config as needed here.
  // e.g. `config.plugins.push(new MyPlugin())`
  return {
    ...config,
    entry: ['webpack/hot/poll?100', ...config.entry.main],
    externals: [
      nodeExternals({
        main: './src/main.ts',
        tsConfig: './tsconfig.app.json',
        assets: ['./src/assets'],
        optimization: false,
        outputHashing: 'none',
        allowlist: ['webpack/hot/poll?100'],
      }),
    ],
    plugins: [
      ...config.plugins,
      new webpack.HotModuleReplacementPlugin(),
      new webpack.WatchIgnorePlugin({
        paths: [/\.js$/, /\.d\.ts$/],
      }),
    ],
  };
});

project.json

{
  "name": "your-nest-app",
  "$schema": "../node_modules/nx/schemas/project-schema.json",
  "sourceRoot": "your-nest-app/src",
  "projectType": "application",
  "tags": [],
  "targets": {
    "build": {
      "executor": "@nx/webpack:webpack",
      "outputs": [
        "{options.outputPath}"
      ],
      "defaultConfiguration": "production",
      "options": {
        "target": "node",
        "compiler": "tsc",
        "outputPath": "dist/your-nest-app",
        "main": "your-nest-app/src/main.ts",
        "tsConfig": "your-nest-app/tsconfig.app.json",
        "assets": [
          "your-nest-app/src/assets"
        ],
        "isolatedConfig": true
      },
      "configurations": {
        "development": {
          "webpackConfig": "your-nest-app/webpack.hmr.config.js"
        },
        "production": {
          "webpackConfig": "your-nest-app/webpack.config.js",
          "generatePackageJson": true
        }
      }
    },
    "serve": {
      "executor": "@nx/js:node",
      "defaultConfiguration": "development",
      "options": {
        "buildTarget": "your-nest-app:build"
      },
      "configurations": {
        "development": {
          "watch": true,
          "buildTarget": "your-nest-app:build:development"
        },
        "production": {
          "buildTarget": "your-nest-app:build:production"
        }
      }
    }
  }
}

main.ts

/**
 * This is not a production server yet!
 * This is only a minimal backend to get started.
 */

declare const module: any;

import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';

import { AppModule } from './app/app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const globalPrefix = 'api';
  app.setGlobalPrefix(globalPrefix);
  const port = process.env.PORT || 3000;
  await app.listen(port);
  Logger.log(
    `🚀 Application is running on: http://localhost:${port}/${globalPrefix}`
  );
  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}

bootstrap();

paullryan avatar Apr 05 '24 17:04 paullryan

@paullryan your setup works, but the app seems to be restarting twice: Once after the HMR updated the module, and a second time after it. Same config as yours. Do you have any suggestions?

svetlyr avatar Apr 11 '24 00:04 svetlyr

For me API is not available in browser till this second reload happens (Maybe due to fact that im using proxy in angular app..). And this 2 reloads take more time than one without HMR - so disabled it at all.

It is quite obvious than whole this NX moved away from Angular to some 'cloud-things' and adding executors for Rust and they have no intention to support useful things like Nestjs. There will be no SWC and no HMR.

itspers avatar May 02 '24 21:05 itspers

I'm on nx 19 and nestjs 10. I am also seeing the double refresh. The first refresh is super fast though! Would be great if there were a fix for HMR!

fourgates avatar May 16 '24 04:05 fourgates

I can confirm the trick from @paullryan works on latest nx 19 and nestjs, with double refresh problem. I tried playing with webpack config a bit with no luck. Debounce did not help either.

EDIT: I noticed that module.hot.dispose() is called only once on file change, however the app restarts a second time.

ardabeyazoglu avatar May 24 '24 13:05 ardabeyazoglu

@svetlyr sorry I'm not using this that heavily at the moment so am unsure about getting the double restart to stop, I did notice that as well. I'm guessing it needs to be addressed deeper in the hot implementation for this module as it's probably doing a small (manifest) change that is causing the second restart. @ndcunningham that's where I'd start in fixing that portion of the hot reload.

paullryan avatar May 24 '24 15:05 paullryan

I think it's related https://github.com/nrwl/nx/issues/20963

dima11221122 avatar Jun 01 '24 14:06 dima11221122