nestjs / nest-cli

CLI tool for Nest applications 🍹
https://nestjs.com
Other
1.97k stars 394 forks source link

The `roodDir` compiler option not being respected when using SWC #2486

Open DaleSeo opened 10 months ago

DaleSeo commented 10 months ago

Is there an existing issue for this?

Current behavior

The rootDir compiler option in tsconfig.json is not being respected when building a NestJS project with SWC. When SWC is not used, the rootDir compiler option determines the directory structure in the output directory.

Minimum reproduction code

https://github.com/DaleSeo/nestjs-typescript-starter-edqvzv

Steps to reproduce

  1. clone the above repository
  2. run npm i
  3. run nest build and check the contents of the generated dist directory

Shot 2023-12-23 at 22 12 32@2x

  1. run nest build -b swc --type-check and check the contents of the generated dist directory

Shot 2023-12-23 at 22 13 04@2x

  1. notice that the directory structure is different (the src directory has disappeared).

Expected behavior

Both nest build and nest build -b swc --type-check should generate identical build outputs for consumers who wish to utilize the swc builder.

Package

Other package

No response

NestJS version

10.3.0

Packages versions

  "dependencies": {
    "@nestjs/common": "^10.0.0",
    "@nestjs/core": "^10.0.0",
    "@nestjs/platform-express": "^10.0.0",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^7.8.1"
  },
  "devDependencies": {
    "@nestjs/cli": "^10.0.0",
    "@nestjs/schematics": "^10.0.0",
    "@nestjs/testing": "^10.0.0",
    "@swc/cli": "^0.1.63",
    "@swc/core": "^1.3.101",
    "@types/express": "^4.17.17",
    "@types/jest": "^29.5.2",
    "@types/node": "^20.3.1",
    "@types/supertest": "^2.0.12",
    "@typescript-eslint/eslint-plugin": "^6.0.0",
    "@typescript-eslint/parser": "^6.0.0",
    "eslint": "^8.42.0",
    "eslint-config-prettier": "^9.0.0",
    "eslint-plugin-prettier": "^5.0.0",
    "jest": "^29.5.0",
    "prettier": "^3.0.0",
    "source-map-support": "^0.5.21",
    "supertest": "^6.3.3",
    "ts-jest": "^29.1.0",
    "ts-loader": "^9.4.3",
    "ts-node": "^10.9.1",
    "tsconfig-paths": "^4.2.0",
    "typescript": "^5.1.3"
  },

Node.js version

18.17.0

In which operating systems have you tested?

Other

No response

nikhilro commented 10 months ago

Same Issue. (Different dist structure when using SWC)

jmcdo29 commented 10 months ago

I want to point out that if you take Nest's default .swcrc

.swcrc ```json { "module": { "type": "commonjs" }, "jsc": { "target": "es2021", "parser": { "syntax": "typescript", "decorators": true, "dynamicImport": true }, "transform": { "legacyDecorator": true, "decoratorMetadata": true, "useDefineForClassFields": false }, "keepClassNames": true, "baseUrl": "./" }, "minify": false } ```

And then run swc ./ -d dist-swc --source-root ./ to mimic the rootDir option (unless there's another swc option I missed) it still outputs directly to dist-swc, not dist-swc/src

kamilmysliwiec commented 9 months ago

Why do you have src dir in dist while compiling with tsc in the first place? Do you have any ts files outside src you wish to compile?

nikhilro commented 9 months ago

Yup exactly, we have files outside src we wish to compile

DaleSeo commented 9 months ago

We also have folders like scripts that contain some TypeScript code. To clarify, I believe this issue is to suggest making it configurable through tsconfig.json instead of enforcing a specific folder structure. This will make the transition to SWC easier for most projects.

kareemalkoul commented 8 months ago

any progress?

williamdclt commented 7 months ago

Having the same issue with @nestjs/cli@10.3.2. I'm finding that pnpm swc . -d dist works fine (as well as tsc):

dist/
    src/
        main.js
    scripts/
        some-script.js
src/
    main.ts
scripts/
    some-script.ts

but nest build with SWC builder doesn't:

dist/
    main.js
    some-script.js
src/
    main.ts
scripts/
    some-script.ts

My src/ and script/ output are mixed up!

My .swcrc:

{
  "$schema": "https://json.schemastore.org/swcrc",
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true,
      "decorators": true,
      "dynamicImport": true
    },
    "baseUrl": ".",
    "target": "es2021",
    "loose": false,
    "externalHelpers": false,
    "transform": {
      "react": {
        "runtime": "automatic",
        "importSource": "@emotion/react"
      }
    }
  },
  "module": {
    "type": "commonjs",
    "strict": true,
    "strictMode": true,
    "lazy": true,
    "noInterop": false
  },
  "sourceMaps": true,
  "exclude": ["node_modules", "dist"]
}

my nest-cli.json

{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": ".",
  "entryFile": "src/index",
  "compilerOptions": {
    "deleteOutDir": true,
    "tsConfigPath": "tsconfig.build.json",
    "manualRestart": true,
    "builder": {
      "type": "swc"
    }
  }
}

my tsconfig.json:

{
  "compilerOptions": {
    "allowJs": false,
    "module": "commonjs",
    "noImplicitAny": false,
    "removeComments": true,
    "noLib": false,
    "isolatedModules": false,
    "allowSyntheticDefaultImports": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es2021",
    "esModuleInterop": true,
    "sourceMap": true,
    "jsx": "react",
    "resolveJsonModule": true,
    "strictNullChecks": true,
    "skipLibCheck": true,
    "outDir": "./dist",
    "rootDir": ".",
    "incremental": true
  },
  "include": [
    "src/*.ts",
    "src/**/*.ts",
    "scripts/*.ts",
  ],
  "exclude": ["node_modules", "dist"]
}
Uki884 commented 3 months ago

@williamdclt

I encountered the same issue, and it was caused by the --strip-leading-paths option being enabled by default. https://swc.rs/docs/usage/cli#–strip-leading-paths

The problem was fixed by changing it as follows:

nest-cli.json

 "builder": {
 "type": "swc",
 "options": {
   "stripLeadingPaths": false
 }
},

Feel free to let me know if you need any further assistance!

Uki884 commented 3 months ago

Additional Information:

The following needs to be added:

"builder": {
  "type": "swc",
  "options": {
    "stripLeadingPaths": false,
    "includeDotfiles": true
  }
}

With this change, it will work correctly even in watch mode.

kamilmysliwiec commented 2 weeks ago

@Uki884 would you like to create a PR to the docs with this info?