nrwl / nx

Smart Monorepos · Fast CI
https://nx.dev
MIT License
23.54k stars 2.35k forks source link

nestjs app is served with `--node-env=production` #26761

Open docentYT opened 4 months ago

docentYT commented 4 months ago

Current Behavior

When running nx serve nestjsapp, webpack builds it in a production mode.

Expected Behavior

It should be served with --node-env=development.

GitHub Repo

No response

Steps to Reproduce

See #22880

Nx Report

Node   : 20.12.1
OS     : win32-x64
npm    : 10.5.0

nx (global)        : 19.1.1
nx                 : 19.3.2
@nx/js             : 19.3.2
@nx/jest           : 19.3.2
@nx/linter         : 19.3.2
@nx/eslint         : 19.3.2
@nx/workspace      : 19.3.2
@nx/angular        : 19.3.2
@nx/devkit         : 19.3.2
@nx/eslint-plugin  : 19.3.2
@nx/nest           : 19.3.2
@nx/node           : 19.3.2
@nx/playwright     : 19.3.2
@nrwl/tao          : 19.3.2
@nx/web            : 19.3.2
@nx/webpack        : 19.3.2
typescript         : 5.4.5
---------------------------------------
Registered Plugins:
@nx/playwright/plugin
@nx/eslint/plugin
@nx/webpack/plugin

Failure Logs

No response

Package Manager Version

No response

Operating System

Additional Information

No response

morgnism commented 2 months ago

Having the same issue. The docs state that running nx serve my-nest-app runs build target in watch mode, but this isn't the case.

cdoky commented 1 month ago

image +1,have any solutions?

morgnism commented 1 month ago

Correcting my comment from earlier, I found that running the server target DID run the server in watch mode, but it uses the production build target first and restarts the build on subsequent file changes.

This isn't a huge problem, but it can make it harder to decipher errors when you miss a provider.

ninode97 commented 1 month ago

Same issue for me:

intenso@fedora:~/Coding/fibalter/carhis$ nx build api --configuration development --verbose

> nx run api:build  [existing outputs match the cache, left as is]

> webpack-cli build --node-env=production

chunk (runtime: main) main.js (main) 90.4 KiB [entry] [rendered]
webpack compiled successfully (0cf27dd0826c948b)

———————————————————————————————————————————————————————————————————————

 NX   Successfully ran target build for project api

Nx read the output from the cache instead of running the command for 1 out of 1 tasks.

intenso@fedora:~/Coding/fibalter/carhis$ 
intenso@fedora:~/Coding/fibalter/carhis$ 
intenso@fedora:~/Coding/fibalter/carhis$ nx build api --configuration development --verbos^C
intenso@fedora:~/Coding/fibalter/carhis$ ^C
intenso@fedora:~/Coding/fibalter/carhis$ nx --version
Nx Version:
- Local: v19.7.0
- Global: v19.6.5
intenso@fedora:~/Coding/fibalter/carhis$ nx^C
intenso@fedora:~/Coding/fibalter/carhis$ cat package.json 
{
  "name": "@mobile/source",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "shadcn:add": "npx shadcn-ui@latest add --overwrite",
    "shadcn:update": "node ./libs/web-ui/index.js",
    "web-ui:add": "npm run shadcn:add && npm run shadcn:update",
    "dev": "nx run-many --all --skip-nx-cache --parallel --targets=serve -p api web",
    "dev:mobile": "nx serve mobile",
    "email:dev": "email dev --dir ./apps/api/src/email/templates"
  },
  "private": true,
  "dependencies": {
    "@dnd-kit/core": "^6.1.0",
    "@dnd-kit/sortable": "^8.0.0",
    "@dnd-kit/utilities": "^3.2.2",
    "@expo/metro-config": "~0.18.1",
    "@expo/metro-runtime": "~3.2.1",
    "@expo/vector-icons": "^14.0.2",
    "@hookform/resolvers": "^3.4.2",
    "@nestjs/common": "^10.0.2",
    "@nestjs/config": "^3.2.2",
    "@nestjs/core": "^10.0.2",
    "@nestjs/event-emitter": "^2.0.4",
    "@nestjs/jwt": "^10.2.0",
    "@nestjs/mapped-types": "^2.0.5",
    "@nestjs/mongoose": "^10.0.6",
    "@nestjs/passport": "^10.0.3",
    "@nestjs/platform-express": "^10.0.2",
    "@nestjs/throttler": "^5.1.2",
    "@nivo/bar": "^0.87.0",
    "@nivo/core": "^0.87.0",
    "@nivo/line": "^0.87.0",
    "@nivo/pie": "^0.87.0",
    "@radix-ui/react-accordion": "^1.1.2",
    "@radix-ui/react-alert-dialog": "^1.0.5",
    "@radix-ui/react-aspect-ratio": "^1.0.3",
    "@radix-ui/react-avatar": "^1.0.4",
    "@radix-ui/react-checkbox": "^1.0.4",
    "@radix-ui/react-collapsible": "^1.0.3",
    "@radix-ui/react-context-menu": "^2.1.5",
    "@radix-ui/react-dialog": "^1.0.5",
    "@radix-ui/react-dropdown-menu": "^2.0.6",
    "@radix-ui/react-hover-card": "^1.0.7",
    "@radix-ui/react-icons": "^1.3.0",
    "@radix-ui/react-label": "^2.0.2",
    "@radix-ui/react-menubar": "^1.0.4",
    "@radix-ui/react-navigation-menu": "^1.1.4",
    "@radix-ui/react-popover": "^1.0.7",
    "@radix-ui/react-progress": "^1.0.3",
    "@radix-ui/react-radio-group": "^1.1.3",
    "@radix-ui/react-scroll-area": "^1.0.5",
    "@radix-ui/react-select": "^2.0.0",
    "@radix-ui/react-separator": "^1.0.3",
    "@radix-ui/react-slider": "^1.1.2",
    "@radix-ui/react-slot": "^1.0.2",
    "@radix-ui/react-switch": "^1.0.3",
    "@radix-ui/react-tabs": "^1.0.4",
    "@radix-ui/react-toast": "^1.1.5",
    "@radix-ui/react-toggle": "^1.0.3",
    "@radix-ui/react-toggle-group": "^1.0.4",
    "@radix-ui/react-tooltip": "^1.0.7",
    "@react-email/components": "0.0.21",
    "@react-email/render": "^0.0.16",
    "@react-native-community/slider": "4.5.2",
    "@react-navigation/bottom-tabs": "^6.6.1",
    "@react-navigation/native": "^6.1.18",
    "@sendgrid/mail": "^8.1.3",
    "@tanstack/react-table": "^8.17.3",
    "aws-sdk": "^2.1655.0",
    "axios": "^1.7.2",
    "bcrypt": "^5.1.1",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.14.1",
    "class-variance-authority": "^0.7.0",
    "clsx": "^2.1.1",
    "cmdk": "^1.0.0",
    "cookie-parser": "^1.4.6",
    "date-fns": "^3.6.0",
    "embla-carousel-react": "^8.1.3",
    "expo": "~51.0.8",
    "expo-blur": "^13.0.2",
    "expo-constants": "~16.0.2",
    "expo-linear-gradient": "~13.0.2",
    "expo-linking": "~6.3.1",
    "expo-navigation-bar": "~3.0.7",
    "expo-network": "^6.0.1",
    "expo-router": "~3.5.23",
    "expo-secure-store": "^13.0.2",
    "expo-splash-screen": "~0.27.4",
    "expo-status-bar": "~1.12.1",
    "framer-motion": "^11.3.2",
    "fs-extra": "^11.2.0",
    "helmet": "^7.1.0",
    "input-otp": "^1.2.4",
    "just-diff": "^6.0.2",
    "lucide-react": "^0.379.0",
    "lucide-react-native": "^0.439.0",
    "mobx": "^6.12.3",
    "mobx-react-lite": "^4.0.7",
    "mongoose": "^8.4.0",
    "moti": "^0.29.0",
    "next-themes": "^0.3.0",
    "passport": "^0.7.0",
    "passport-jwt": "^4.0.1",
    "react": "18.3.1",
    "react-day-picker": "^8.10.1",
    "react-dom": "18.3.1",
    "react-email": "2.1.5",
    "react-error-boundary": "^4.0.13",
    "react-hook-form": "^7.51.5",
    "react-native": "0.74.1",
    "react-native-progress": "^5.0.1",
    "react-native-reanimated": "~3.10.1",
    "react-native-safe-area-context": "4.10.5",
    "react-native-screens": "3.31.1",
    "react-native-svg": "15.2.0",
    "react-native-svg-transformer": "1.3.0",
    "react-native-toast-message": "^2.2.0",
    "react-native-web": "~0.19.11",
    "react-resizable-panels": "^2.0.19",
    "react-router-dom": "^6.23.1",
    "react-signature-canvas": "^1.0.6",
    "recharts": "^2.12.7",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^7.8.0",
    "sonner": "^1.4.41",
    "tailwind-merge": "^2.3.0",
    "tailwindcss-animate": "^1.0.7",
    "tslib": "^2.3.0",
    "vaul": "^0.9.1",
    "zod": "^3.23.8"
  },
  "devDependencies": {
    "@babel/core": "^7.14.5",
    "@babel/preset-react": "^7.14.5",
    "@babel/runtime": "7.24.5",
    "@expo/cli": "~0.18.13",
    "@nestjs/schematics": "^10.0.1",
    "@nestjs/testing": "^10.0.2",
    "@nx/eslint": "19.7.0",
    "@nx/eslint-plugin": "19.7.0",
    "@nx/expo": "19.7.0",
    "@nx/jest": "19.7.0",
    "@nx/js": "19.7.0",
    "@nx/nest": "19.6.5",
    "@nx/node": "19.6.5",
    "@nx/react": "19.6.5",
    "@nx/vite": "19.6.5",
    "@nx/web": "19.6.5",
    "@nx/webpack": "19.6.5",
    "@nx/workspace": "19.7.0",
    "@swc-node/register": "~1.9.1",
    "@swc/cli": "~0.3.12",
    "@swc/core": "~1.5.7",
    "@swc/helpers": "~0.5.11",
    "@testing-library/jest-native": "~5.4.3",
    "@testing-library/react": "16.0.0",
    "@testing-library/react-native": "~12.5.0",
    "@types/bcrypt": "^5.0.2",
    "@types/cookie-parser": "^1.4.7",
    "@types/express": "^4.17.21",
    "@types/fs-extra": "^11.0.4",
    "@types/jest": "^29.5.12",
    "@types/multer": "^1.4.11",
    "@types/node": "18.16.9",
    "@types/react": "18.3.1",
    "@types/react-dom": "18.3.0",
    "@types/react-native": "^0.73.0",
    "@types/react-signature-canvas": "^1.0.5",
    "@typescript-eslint/eslint-plugin": "^7.16.0",
    "@typescript-eslint/parser": "^7.16.0",
    "@vitejs/plugin-react": "^4.3.1",
    "@vitest/ui": "^1.6.0",
    "autoprefixer": "10.4.19",
    "babel-jest": "^29.7.0",
    "babel-preset-expo": "~11.0.0",
    "eslint": "~8.57.0",
    "eslint-config-prettier": "^9.0.0",
    "eslint-plugin-import": "2.27.5",
    "eslint-plugin-jsx-a11y": "6.7.1",
    "eslint-plugin-react": "7.32.2",
    "eslint-plugin-react-hooks": "4.6.0",
    "jest": "^29.7.0",
    "jest-environment-jsdom": "^29.7.0",
    "jest-environment-node": "^29.7.0",
    "jest-expo": "~51.0.2",
    "jsdom": "~24.1.0",
    "nx": "19.7.0",
    "postcss": "8.4.38",
    "prettier": "^2.6.2",
    "react-test-renderer": "18.2.0",
    "tailwindcss": "3.4.4",
    "ts-jest": "^29.1.0",
    "ts-node": "10.9.1",
    "typescript": "~5.5.2",
    "vite": "~5.2.13",
    "vite-plugin-dts": "~3.9.1",
    "vitest": "^1.6.0",
    "webpack-cli": "^5.1.4"
  }
}
intenso@fedora:~/Coding/fibalter/carhis$ 
SeanLatimer commented 1 month ago

It appears to be forcefully passing production here.

I changed around some of the targets in project.json and it appears to work ok other than build is always run with NODE_ENV=production. serve does override to development which can be confirmed by throwing console.log(process.env.NODE_ENV) in webpack.config.js.

{
  "name": "server",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "sourceRoot": "apps/server/src",
  "projectType": "application",
  "tags": [],
  "targets": {
    "build": {
      "executor": "@nx/webpack:webpack",
      "defaultConfiguration": "production",
      "outputs": ["{options.outputPath}"],
      "options": {
        "outputPath": "dist/apps/server",
        "webpackConfig": "apps/server/webpack.config.js"
      }
    },
    "serve": {
      "executor": "@nx/js:node",
      "defaultConfiguration": "development",
      "options": {
        "buildTarget": "server:build",
        "runBuildTargetDependencies": false
      },
      "configurations": {
        "development": {},
        "production": {}
      }
    }
  }
}
// webpack.config.js
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
const { join } = require('path');

console.log(process.env.NODE_ENV);
module.exports = {
  output: {
    path: join(__dirname, '../../dist/apps/server'),
  },
  stats: 'errors-only',
  plugins: [
    new NxAppWebpackPlugin({
      target: 'node',
      compiler: 'tsc',
      main: './src/main.ts',
      tsConfig: './tsconfig.app.json',
      assets: ['./src/assets'],
      optimization: false,
      outputHashing: 'none',
      generatePackageJson: process.env.NODE_ENV === 'production',
      sourceMap: process.env.NODE_ENV === 'development',
    }),
  ],
};
cdoky commented 1 month ago

haha, the solution is here: https://github.com/nrwl/nx/issues/21517#issuecomment-2242902642

morgnism commented 1 month ago

@cdoky This solution works up to the point of hot reload failing, as you mentioned earlier. Have you figured out a workaround for this?

cdoky commented 1 month ago

@morgnism you can use this solution: https://github.com/nrwl/nx/issues/21517#issuecomment-2242902642, if you hot reload failed, you can fixed it by nx reset

rsaenen commented 1 month ago

I'm facing this issue with slow "hot reloading" (10x slower than before). You can try to edit this file in your node_modules (then run nx reset) and you will see that it's still slow to reload after a file change.

I guess there's an issue with the webpack configuration, webpack won't hot reloading because on each file change, it will build with production mode your app.

IMO it should run a webpack-cli watch with dev mode and not rebuild the app.

My webpack configuration that enable debug :

const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
const { join } = require('path');

module.exports = {
  output: {
    path: join(__dirname, '../../dist/apps/<your-app>'),
  },
  plugins: [
    new NxAppWebpackPlugin({
      target: 'node',
      compiler: 'tsc',
      main: './src/main.ts',
      tsConfig: './tsconfig.app.json',
      assets: ['./src/assets'],
      optimization: false,
      outputHashing: 'none',
      sourceMap: process.env.ENV !== 'production',
    }),
  ],
};
slyk commented 2 weeks ago

If you add a build task in project.json, you can perform breakpoint debugging, but hotreload will fail.

"targets": { "build": { "executor": "@nx/webpack:webpack", "options": { "outputPath": "dist/apps/api", "webpackConfig": "apps/api/webpack.config.js" } }, "serve":...

added this to my app project.json and breakpoints start to work. THANK you my friend!!

All newcomers that will try to nestjs with NX now will not have breakpoints until they google that issue? that is very bad for such platform :(

cdoky commented 1 week ago

@slyk The solution is here: https://github.com/nrwl/nx/issues/21517#issuecomment-2242902642. Reset you project.json, Just modify the webpack.config.js

SinPP commented 1 week ago

This is not fixing the mentioned problem.

The dev mode should not try to EVER build any production libs. It makes the nx system completely unusable for small projects. I have one dependent library and a simple file change takes around 3 minutes before the dev server starts up again. The only reason is that it tries to build dependent libraries, which it should NEVER ever do in development mode. Even starting the nestjs service in production mode is flawed.

Any input from the nx team? When is a fix to be expected?

rsaenen commented 6 days ago

To enhance DX, you can use nest-cli for dev purposes like local serve.

  1. Create nest-cli.json

    {
    "$schema": "https://json.schemastore.org/nest-cli",
    "collection": "@nestjs/schematics",
    "sourceRoot": "apps/<project-1>/src",
    "monorepo": true,
    "root": "apps/<project-1>",
    "compilerOptions": {
    "tsConfigPath": "apps/<project-1>/tsconfig.nest.json"
    },
    "projects": {
    "<project-1>": {
      "type": "application",
      "root": "apps/<project-1>",
      "entryFile": "main",
      "sourceRoot": "apps/<project-1>/src",
      "compilerOptions": {
        "tsConfigPath": "apps/<project-1>/tsconfig.nest.json"
      }
    },
    "<project-2>": {
      "type": "application",
      "root": "apps/<project-2>",
      "entryFile": "main",
      "sourceRoot": "apps/<project-2>/src",
      "compilerOptions": {
        "tsConfigPath": "apps/<project-2>/tsconfig.nest.json"
      }
    }
    }
    }
  2. Create apps/<project-1>/tsconfig.nest.json

    {
    "extends": "./tsconfig.json",
    "compilerOptions": {
    "outDir": "../../dist/apps/<project-1>",
    "module": "commonjs",
    "types": ["node"],
    "emitDecoratorMetadata": true,
    "target": "es2021"
    },
    "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
    "include": ["src/**/*.ts"]
    }
  3. Update apps/<project-1>/project.json to add a target

    {
    "name": "<project-1>",
    "$schema": "../../node_modules/nx/schemas/project-schema.json",
    "sourceRoot": "apps/<project-1>/src",
    "projectType": "application",
    "tags": [],
    "targets": {
    ...
    "local": {
      "executor": "nx:run-commands",
      "options": {
        "command": "nest start <project-1> --debug --watch --preserveWatchOutput"
      }
    }
    }
    }
  4. Update package.json scripts

    "scripts": {
    "dev": "nx run-many --all --target=local --output-style=stream-without-prefixes --verbose --parallel=<your number of projects>", 

    (be aware that .env.local ou .env will be loaded)

  5. If you have projects without nestjs (like react, vue...), add a target local

    "local": {
      "executor": "nx:run-commands",
      "options": {
        "command": "nx serve <other-project>"
      }
    },
  6. You can run npm run dev with faster reload and debug