Open gremo opened 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?
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.
Thanks!
There are no docs for TypeScript Compiler API with Project references so far. I'd recommend sticking with the existing configuration for now.
What do you mean with "existing configuration for now"?
With tsc
& tsc-watch
. Migration to NestJS CLI is not required, there are no breaking changes
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.
First, run tsc -b
manually. Once the compilation is complete, you'll be able to run nest build
without errors
@kamilmysliwiec thank you a lot. I don't like to build with tsc
before building with nest
. I'll stick with the "old" scripts.
Are there any changes on this?
Just wrote a workaround on this problem for you guys on Yarn Workspaces:
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}`);
})
});
{
"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.
Are there any changes on this? I would still love to see the -b
flag for tsc
@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 ...
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?
Is there any update on this? This would be a very useful feature for me and my company
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)
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"
}
]
}
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 š
Hi, I'm also interested in supporting typescript references
This would be really helpful if npm run start:dev
recompiled when references change
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.
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.
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
I want to develop a plug-in architecture and need to use it
Does the CLi support the build flag (
-b
fortsc
)? It seems not.... I'm trying to setup a project with TypeScript project references... any help?