nest-cli icon indicating copy to clipboard operation
nest-cli copied to clipboard

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

Open DaleSeo opened this issue 2 years ago • 10 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

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

  • [X] I don't know. Or some 3rd-party package
  • [ ] @nestjs/common
  • [ ] @nestjs/core
  • [ ] @nestjs/microservices
  • [ ] @nestjs/platform-express
  • [ ] @nestjs/platform-fastify
  • [ ] @nestjs/platform-socket.io
  • [ ] @nestjs/platform-ws
  • [ ] @nestjs/testing
  • [ ] @nestjs/websockets
  • [ ] Other (see below)

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?

  • [X] macOS
  • [ ] Windows
  • [ ] Linux

Other

No response

DaleSeo avatar Dec 23 '23 13:12 DaleSeo

Same Issue. (Different dist structure when using SWC)

nikhilro avatar Dec 27 '23 20:12 nikhilro

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

.swcrc
{
  "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

jmcdo29 avatar Dec 27 '23 21:12 jmcdo29

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?

kamilmysliwiec avatar Feb 01 '24 07:02 kamilmysliwiec

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

nikhilro avatar Feb 01 '24 18:02 nikhilro

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.

DaleSeo avatar Feb 05 '24 16:02 DaleSeo

any progress?

kareemalkoul avatar Feb 20 '24 11:02 kareemalkoul

Having the same issue with @nestjs/[email protected]. 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"]
}

williamdclt avatar Mar 21 '24 13:03 williamdclt

@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 avatar Jul 17 '24 10:07 Uki884

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.

Uki884 avatar Jul 22 '24 12:07 Uki884