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

Support for "build" option for TypeScript project references?

Open gremo opened this issue 4 years ago • 23 comments

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

gremo avatar Oct 01 '19 16:10 gremo

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

kamilmysliwiec avatar Oct 02 '19 06:10 kamilmysliwiec

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.

gremo avatar Oct 02 '19 07:10 gremo

Thanks!

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

kamilmysliwiec avatar Oct 02 '19 11:10 kamilmysliwiec

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

gremo avatar Oct 02 '19 11:10 gremo

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

kamilmysliwiec avatar Oct 02 '19 11:10 kamilmysliwiec

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

kamilmysliwiec avatar Oct 02 '19 15:10 kamilmysliwiec

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

gremo avatar Oct 03 '19 08:10 gremo

Are there any changes on this?

perevezencev avatar May 01 '20 13:05 perevezencev

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.

brvnonascimento avatar Nov 30 '20 21:11 brvnonascimento

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

hartherbert avatar Aug 21 '21 11:08 hartherbert

@kamilmysliwiec the above recommendation does not work on @nestjs/[email protected] 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 ...

emilhdiaz avatar Jan 20 '22 20:01 emilhdiaz

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?

guilhermegjr avatar Feb 23 '22 00:02 guilhermegjr

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

tylerthecoder avatar Apr 22 '22 19:04 tylerthecoder

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)

jbbeal avatar Aug 21 '22 23:08 jbbeal

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"
    }
  ]
}

Fanda36 avatar Dec 07 '22 09:12 Fanda36

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 😊

andreykrupskii avatar Feb 10 '23 10:02 andreykrupskii

Hi, I'm also interested in supporting typescript references

monrus avatar Feb 15 '23 06:02 monrus

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

Upperfoot avatar Mar 02 '23 20:03 Upperfoot

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 avatar Mar 07 '23 18:03 nbryan

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.

nbryan avatar Mar 07 '23 18:03 nbryan

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

aralroca avatar Mar 16 '23 14:03 aralroca

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

yuntian001 avatar May 10 '23 03:05 yuntian001

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

kamilmysliwiec avatar May 15 '23 08:05 kamilmysliwiec