nx icon indicating copy to clipboard operation
nx copied to clipboard

Add swc as an option to use with node/nestjs builder

Open tonivj5 opened this issue 3 years ago โ€ข 7 comments

Description

As https://github.com/swc-project/swc/pull/3459 has fixed the use of legacy-decorators, it'd awesome to be able of use swc as compiler/bundler to reduce typescript compilation time ๐Ÿš€

Motivation

Reduce time of tsc.

Suggested Implementation

swc is used with @nrwl/js and others, use it with @nrwl/node (nestjs) too

Alternate Implementations

esbuild doesn't support ~legacy decorators~ emitDecoratorMetadata ๐Ÿ˜ข

tonivj5 avatar Feb 08 '22 10:02 tonivj5

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 Oct 23 '22 00:10 github-actions[bot]

Up

tonivj5 avatar Oct 23 '22 07:10 tonivj5

Looks like its coming to NestCLI so it would be great for Nx to also provide it as an option https://twitter.com/kammysliwiec/status/1664192006019506178?s=20

kdawgwilk avatar Jun 01 '23 19:06 kdawgwilk

bump

arivera-xealth avatar Jun 29 '23 14:06 arivera-xealth

I think many of us would love to see this.

drackp2m avatar Jun 29 '23 21:06 drackp2m

Up

AdhamMoussa avatar Jul 03 '23 15:07 AdhamMoussa

NestJS CLI shipped this in v10 https://trilon.io/blog/nestjs-10-is-now-available#nestjs-%EF%B8%8F-swc

kdawgwilk avatar Jul 03 '23 19:07 kdawgwilk

Given that the latest version of Nx seems to be slowing down the NestJS development process, I was wondering if there are any plans to integrate SWC to potentially improve performance. ๐Ÿค”

ggagosh avatar Jul 11 '23 10:07 ggagosh

Is there anyone willing to work on this?

michaeljauk avatar Jul 11 '23 10:07 michaeljauk

+1 on this. Adding support for SWC would be great for NestJs apps. I've managed to get SWC working with NestJs, but compilation fails on NX library imports.

DavidFencl avatar Jul 18 '23 15:07 DavidFencl

+1

om-mahato avatar Jul 27 '23 09:07 om-mahato

+1. This will make development experience so much better.

thenglong avatar Jul 28 '23 02:07 thenglong

Is it possible to use this nest start -b swc instead of default nx builder? This nx has interesting curve: first when you start using it - it feels 'right', but then with every update more and more problems occur with angular, react, nest.. to the point where im now sure maintaining just 10 stanalone apps would be much simpler.

itspers avatar Jul 29 '23 19:07 itspers

Up.

mhdismail avatar Aug 06 '23 18:08 mhdismail

@itspers

I thought I made it working with nest start -b swc, but when I tried to import an nx generated library, the paths were not compiled at all

NestJS so slow in dev since upgrade....

jacqueslareau avatar Aug 16 '23 13:08 jacqueslareau

+1

mustafaersoyer avatar Aug 21 '23 06:08 mustafaersoyer

Up

Jeff909Dev avatar Aug 22 '23 06:08 Jeff909Dev

BTW is there separate issue talking about slow NestJS watch mode? It's seriously annoying. My pretty small app takes 20-30 seconds to recompile every time something changes. It also takes a lot of time for deamon to even notice something changed. It used to be almost instant in previous NX versions. I can provide link to my repo if necessary.

DavidFencl avatar Aug 22 '23 06:08 DavidFencl

Same @DavidFencl

DobroslavR avatar Sep 15 '23 22:09 DobroslavR

โ˜๏ธ

ak2g avatar Sep 20 '23 10:09 ak2g

๐Ÿ†™

jurienhamaker avatar Sep 28 '23 19:09 jurienhamaker

Can't believe this is not ready yet.

Seeing extremely slow compilation of Nest apps in newest NX versions makes me cry sometimes.

This would solve it pretty easily.

DobroslavR avatar Sep 28 '23 23:09 DobroslavR

๐Ÿ†™

viniciusLouzada avatar Oct 04 '23 04:10 viniciusLouzada

I got my NestJS working with SWC (p.s. I used npx create-nx-workspace@latest for workspace creation)

1. Install parts of SWC that you needed: $ npm install @swc/cli @swc/core @swc/jest

2. Reconfigure your project.json file (generated by NX) like this:

  "name": "nx-nest-boilerplate",
  "$schema": "node_modules/nx/schemas/project-schema.json",
  "sourceRoot": "src",
  "projectType": "application",
  "targets": {
    "build": {
      "executor": "@nx/js:swc",   // <---- Important
      "outputs": [
        "{options.outputPath}"
      ],
      "defaultConfiguration": "production",
      "options": {
        "target": "node",
        "compiler": "swc",       // <---- Important
        "swcrc": ".swcrc",       // <---- Important
        "outputPath": "dist/nx-nest-boilerplate",
        "main": "src/main.ts",
        "tsConfig": "tsconfig.app.json",
        "assets": [
          "src/assets"
        ],
        "isolatedConfig": true
      },
      "configurations": {
        "development": {
          "swcrc": ".swcrc"      // <---- Your development swcrc file
        },
        "production": {
          "swcrc": ".swcrc"      // <---- Your production swcrc file
        }
      }
    },
    "serve": {
     ....

3. Create your .swcrc file:

{
  "$schema": "https://json.schemastore.org/swcrc",
  "sourceMaps": true,
  "module": {
    "type": "commonjs",       // <---- Important
    "strict": true,
    "strictMode": true
  },
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "dynamicImport": true
    },
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": true
    }
  },
  "minify": true
}

Here's my tsconfig.app.json:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "strictNullChecks": true,
    "strict": true,
    "outDir": "./dist/out-tsc",
    "module": "CommonJS",       // <---- Important
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,   // <---- Important (I think)
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "incremental": true,
    "types": ["node"],
    "target": "ES2021"
  },
  "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
  "include": ["src/**/*.ts"]
}

And here's my environment:

"dependencies": {
    "@nestjs/common": "^10.0.2",
    "@nestjs/core": "^10.0.2",
    "@nestjs/platform-express": "^10.0.2",
    "@swc/cli": "^0.1.62",
    "@swc/core": "^1.3.92",
    "@swc/jest": "^0.2.29",
    "axios": "^1.0.0",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^7.8.0",
    "tslib": "^2.3.0"
},

"devDependencies": {
    "@nestjs/schematics": "^10.0.1",
    "@nestjs/testing": "^10.0.2",
    "@nx/eslint-plugin": "16.10.0",
    "@nx/jest": "16.10.0",
    "@nx/js": "16.10.0",
    "@nx/linter": "16.10.0",
    "@nx/nest": "16.10.0",
    "@nx/node": "16.10.0",
    "@nx/webpack": "16.10.0",
    "@nx/workspace": "16.10.0",
    "@types/jest": "^29.4.0",
    "@types/node": "~18.7.1",
    "@typescript-eslint/eslint-plugin": "^5.60.1",
    "@typescript-eslint/parser": "^5.60.1",
    "eslint": "~8.46.0",
    "eslint-config-prettier": "8.1.0",
    "jest": "^29.4.1",
    "jest-environment-node": "^29.4.1",
    "nx": "16.10.0",
    "nx-cloud": "latest",
    "prettier": "^2.6.2",
    "ts-jest": "^29.1.0",
    "ts-node": "10.9.1",
    "typescript": "~5.1.3"
}

c0dewriter avatar Oct 08 '23 14:10 c0dewriter

@c0dewriter can you make public repo with this?

DobroslavR avatar Oct 08 '23 15:10 DobroslavR

{
  "$schema": "https://json.schemastore.org/swcrc",
  "sourceMaps": true,
  "module": {
    "type": "commonjs",       // <---- Important
    "strict": true,
    "strictMode": true
  },
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "dynamicImport": true
    },
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": true
    }
  },
  "minify": true
}

@c0dewriter thanks for these snippets. I can compile a new standalone NestJS app in NX, however imports from libs aren't working for me with this error at build time

 File 'libs/nest-stripe/index.ts' is not under 'rootDir' 'apps/api'. 'rootDir' is expected to contain all source files

wilson208 avatar Oct 08 '23 23:10 wilson208

This is the main issue here and probably why it takes so long. Executor do more stuff than just wrapping underlying tech (like swc). It also has to rewrite your imports depending on the command you run. serve has to read all your sources directly (most likely TypeScript files) from packages/libs directory. In build mode it uses compiled source code from dist. In order to do that it needs to create dynamic configuration files depending on the command and do few other things to wire everything.

If you want all the nice things that nx gives you for monorepo management you have to accept that you won't always be able to use latest and greatest from the framework that nx wraps.

pf1gura avatar Oct 09 '23 10:10 pf1gura

@pf1gura thanks for your insight. Given the solution above uses the existing '@nx/js:swc' executor I made an assumption that this executor would already handle imports from libs. @c0dewriter posted a potential solution, I tried it and gave feedback, I'm just keen for a solution because my NestJS build times have been very slow after the release of v10 and the nx monorepo I work with day to day has 6 different NestJS applications and the DX isn't great right now.

wilson208 avatar Oct 09 '23 11:10 wilson208

If I recall correctly existing swc executor is for libraries only. You can use it in your shared TypeScript libraries to speed up library build times but final build of your application still has to go through node executor (which does not use swc)

pf1gura avatar Oct 09 '23 14:10 pf1gura