nestjs / nest-cli

CLI tool for Nest applications šŸ¹
https://nestjs.com
Other
1.97k stars 394 forks source link

Support for "build" option for TypeScript project references? #392

Open gremo opened 5 years ago

gremo commented 5 years ago

Does the CLi support the build flag (-b for tsc)? It seems not.... I'm trying to setup a project with TypeScript project references... any help?

$ nest build --help
Usage: nest build [options] [app]

Build Nest application

Options:
  -p, --path [path]     Path to tsconfig file
  -w, --watch           Run in watch mode (live-reload)
  --webpack             Use webpack for compilation
  --webpackPath [path]  Path to webpack configuration
  -h, --help            output usage information
kamilmysliwiec commented 5 years ago

I'm not sure whether it makes sense to use TS project references in combination with Nest CLI. Can you share a sample repository?

gremo commented 5 years ago

Hi! Thanks for the reply. Sure, here is an example: https://github.com/gremo/nestangular-boilerplate

As you can see in packages/server/package.json I'm still using the "old" scripts (tsc, ts-node, tsc-watch). Scripts has been all modified to use the -b option. But I'd like to switch to Nest CLI commands. In order to do so, it should support TypeScript project references.

Why I'm using TypeScript project references? That's simple. That is a Yarn workspace project here directory packages/server holds the NestJS application, packages/shared holds common utilities and domain models, while packages/client is an Angular 8 application.

With Yarn workspaces and TS project references I can manage dependencies and output "structure" very easily.

kamilmysliwiec commented 5 years ago

Thanks!

There are no docs for TypeScript Compiler API with Project references so far. I'd recommend sticking with the existing configuration for now.

gremo commented 5 years ago

What do you mean with "existing configuration for now"?

kamilmysliwiec commented 5 years ago

With tsc & tsc-watch. Migration to NestJS CLI is not required, there are no breaking changes

kamilmysliwiec commented 5 years ago

In the latest version of the CLI (^6.10.x), we support project references partially, similarly to this issue: https://github.com/TypeStrong/ts-loader/issues/851#issue-367532340

Copy & pasted from ts-loader (and slightly modified):

Using project references currently requires building referenced projects outside of Nest CLI.

Nest CLI has partial support for project references in that it will load dependent composite projects that are already built, but will not currently build/rebuild those upstream projects. The best way to explain exactly what this means is through an example. Say you have a project with a project reference pointing to the lib/ directory:

tsconfig.json
lib/
  tsconfig.json
  niftyUtil.ts

And weā€™ll assume that the root tsconfig.json has { "references": { "path": "lib" } }, which means that any import of a file thatā€™s part of the lib sub-project is treated as a reference to another project, not just a reference to a TypeScript file. Before discussing how Nest handles this, itā€™s helpful to review at a really basic level what tsc itself does here. If you were to run tsc on this tiny example project, the build would fail with the error:

error TS6305: Output file 'lib/niftyUtil.d.ts' has not been built from source file 'lib/niftyUtil.ts'.

Using project references actually instructs tsc not to build anything thatā€™s part of another project from source, but rather to look for any .d.ts and .js files that have already been generated from a previous build. Since weā€™ve never built the project in lib before, those files donā€™t exist, so building the root project fails. Still just thinking about how tsc works, there are two options to make the build succeed: either run tsc -p lib/tsconfig.json first, or simply run tsc --build, which will figure out that lib hasnā€™t been built and build it first for you.

TEMPORARY SOLUTION

First, run tsc -b manually. Once the compilation is complete, you'll be able to run nest build without errors

gremo commented 5 years ago

@kamilmysliwiec thank you a lot. I don't like to build with tsc before building with nest. I'll stick with the "old" scripts.

perevezencev commented 4 years ago

Are there any changes on this?

brvnonascimento commented 3 years ago

Just wrote a workaround on this problem for you guys on Yarn Workspaces:

  1. Create a "buildReferences.js" file at the root of the package you want to build the references for:
const typescript = require('typescript')
const { exec } = require('child_process')

const tsconfig = typescript.readConfigFile('tsconfig.json', typescript.sys.readFile)
const references = tsconfig.config.references;

references.forEach(({ path }) => {
  exec(`tsc --project ${path}`, () => {
    console.log(`BUILT REFERENCE: ${path}`);
  })
});
  1. Add the following scripts to your package.json file named as followed or "prewhateverscriptyouhave":
  {
    "references:build": "node buildReferences.js",
    "prebuild": "yarn references:build",
    "predev": "yarn references:build"
  }

Might not be the fastest option out there, but I think is better than running "tsc" twice every time.

hartherbert commented 3 years ago

Are there any changes on this? I would still love to see the -b flag for tsc

emilhdiaz commented 2 years ago

@kamilmysliwiec the above recommendation does not work on @nestjs/cli@8.2.0 when the project references point to a module outside of the rootDir.

For example:

/repo
  + frontend
     + main.ts                  <- contains an import from '../shared/foo'
     + tsconfig.json            <- contains project reference to ../shared with rootDir = ./ (aka /repo/frontend)
     + tsconfig.build.json      <- extends tsconfig.json with no modifications
  + backend/
  + shared/
     + foo.ts
     + tsconfig.json            <- the referenced project

The above setup will build fine with:

cd /repo/api && tsc --build

OR

tsc --project /repo/shared
tsc --project /repo/frontend

BUT will fail with cd /repo/api nest build

error TS6307: File '/repo/shared/foo.ts' is not listed within the file list of project '/repo/frontend/tsconfig.build.json'. Projects must list all files or use an 'include' pattern.
  The file is in the program because:
    Imported via '../shared/foo' from file '/repo/frontend/main.ts' with ...
guilhermegjr commented 2 years ago

Hello @kamilmysliwiec. Do you have any updates about it? I saw you suggest not using the nest CLI but I tried to run some combinations of but with no luck. Could you give some advice on it?

tylerthecoder commented 2 years ago

Is there any update on this? This would be a very useful feature for me and my company

jbbeal commented 2 years ago

I've worked around this in some of my projects by modifying the build script in package.json to be: tsc --build && nest build. Similarly, I've modified the start:dev command to be tsc --build && nest start --watch. These make sure that the dependent packages are built before running the nest CLI, but working in a monorepo seems like something that should be a well-supported developer experience using default tools, and should use standard tsc features as much as possible.

(An additional point on getting the --watch behavior to work. The nest bootstrap project, last time I used it, included rimraf dist as a prebuild step. If the depended package was using this, the --watch from the Nest server wouldn't see when I made edits in the dependent package. So, I also had to modify the prebuild step in dependent packages to rimraf dist/*; this prevented the file handle of the dist directory itself from changing. I could have one shell running tsc --build --watch on each of the dependency libraries, then the process running nest build --watch would see changes when files were modified in the dependencies' dist folders)

Fanda36 commented 1 year ago

Hi, I've checked the repository and there is one commit with maybe add support for TS project references - https://github.com/nestjs/nest-cli/commit/cd2d0af6e2aba5b261e91843036a01f0687b1ed7

@kamilmysliwiec do you have an example of how it works, please? I've tried to print the content of https://github.com/nestjs/nest-cli/blob/3bfecfa11567a4a6418546ef055a3c1aa15e3a2a/lib/compiler/helpers/tsconfig-provider.ts#L22 projectReferences but it was undefined. Is the projectReference related to TS project reference? My tsconfig.json with a reference is:

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": true,
    "noImplicitAny": true,
    "strictBindCallApply": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true
  },
  "references": [
    {
      "path": "./../packages/common"
    }
  ]
}
andreykrupskii commented 1 year ago

Hi, is this thread alive? šŸ˜‰ It would be a super helpful feature, as working in a huge monorepo environments without typescript references is painful. Please, tell if there are any plans to support this enchainment šŸ˜Š

monrus commented 1 year ago

Hi, I'm also interested in supporting typescript references

Upperfoot commented 1 year ago

This would be really helpful if npm run start:dev recompiled when references change

nbryan commented 1 year ago

Also interested in this. I don't care about using nest build--it seems redundant with my own build script--but it would be really nice to have nest start --watch work with project references.

nbryan commented 1 year ago

FWIW, for those interested in another solution, I am able to get this working with nodemon. It's just nice to not add extra dependencies.

aralroca commented 1 year ago

Also interested in this... We are working in a mono repo with different projects and want to share a package between them using combine and references, and I think this tsc --build flag is required

yuntian001 commented 1 year ago

I want to develop a plug-in architecture and need to use it

kamilmysliwiec commented 1 year ago

https://github.com/nestjs/nest-cli/issues/392#issuecomment-537538297