Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type check command #3664

Open
JakeGinnivan opened this issue Sep 5, 2020 · 60 comments
Open

Type check command #3664

JakeGinnivan opened this issue Sep 5, 2020 · 60 comments
Assignees

Comments

@JakeGinnivan
Copy link
Contributor

Description

One way I leverage TypeScript is when making a behavioral change to my project is to ensure the source of the change is a compilation mistake.

Being able to run a type check over the entire project through VS Code and use the TypeScript problem matcher to ensure they are surfaced in the Problems tab

Motivation

Being able to surface all build errors in a repo is very handy, especially when making a change to one to the shared projects.

Suggested Implementation

Until the solution file exists, running tsc -p apps/*/tsconfig.json --noEmit --incremental for each app tsconfig?

Alternate Implementations

Maintain a solution tsconfig.all.json, I read there were some issues with having one so having it named differently should stop it being picked up by VSCode. I think we would then need tsconfig.check.json for each project which sets no-emit and incremental.

@JakeGinnivan
Copy link
Contributor Author

I guess a third option is writing a problem matcher for the build cli command?

@vsavkin vsavkin added the scope: misc Misc issues label Sep 15, 2020
@zhangciwu
Copy link

Build command can not cover the code that is not used in any app yet, so a typescript checker is necessary

@zhangciwu
Copy link

typescript-eslint/typescript-eslint#352
And eslint can not cover this case, FYI

@zhangciwu
Copy link

zhangciwu commented Nov 11, 2020

Currently I use tsc -b (in every app/lib dir) for resolution style tsconfig which is by default in nx@10
It does not support noEmit, so need to indicate a path to place the compiled files (in compilerOptions.outDir)
Ref: https://www.typescriptlang.org/docs/handbook/project-references.html

@KeKs0r
Copy link
Contributor

KeKs0r commented Nov 22, 2020

+1 to see a proper solution to just running type checks. I would love to separate my build from type checks in order to parallize them as well as enabling the possibility of running different bundlers that don't do the type checking as well.

@zhangciwu can you elaborate a little bit more on that setup? I tried to achieve something similar, by adding a run-command to all apps / projects e.g.

        "type-check": {
          "builder": "@nrwl/workspace:run-commands",
          "options": {
            "command": "yarn tsc -b apps/client/tsconfig.app.json --incremental"
          }
        }

The problem is when running it for some libs, which is when I am getting the rootDir error:
'rootDir' is expected to contain all source files.
I assume this can be fixed, by manually referencing all projects (a lot of work) and making all of these libs composite and fixing some more configuration issues such as
Composite projects may not disable declaration emit.

The final issue I am stuck here with, that this does not seem to pick up the proper extended tsconfig in my referenced projects. Since I am getting this Cannot find name 'process'. Do you need to install type definitions for node? Try npm i @types/nodeand then addnode to the types field in your tsconfig. although I have types node installed and in the respective tsconfig.

Did you manually run through this whole process or is there a more holistic solution?

@zhangciwu
Copy link

zhangciwu commented Nov 23, 2020

@KeKs0r
I wrote a script to walk all the dir of apps/libs, and run tsc -b in cwd set to that path if there is tsconfig there
It's kind of rough and not that nx style

Tried with nx command and it works well, the command I use is:

       "type-check": {
          "builder": "@nrwl/workspace:run-commands",
          "options": {
            "command": "npm run tsc -- -b ./apps/content/tsconfig.json --incremental"
          }
        }

Some points:

  • To cover all source files, I have a tsconfig.base.json at root, with "rootDir": ".", so it covers all (apps/libs tsconfig extend it)
  • noEmit is not avaliable for composite projects, so make sure to set outDir properly (I use "../../dist/out-tsc", which seems default by nx)
  • Just use tsconfig.json, it will cover all references like app and spec, (and that's the point of -b option of typescript compiler)

@AliYusuf95
Copy link
Contributor

I agree we should have this command

@KeKs0r Did you make it? If so, can you share your configuration?

I tried to configure my app tsconfig.json file but it seems not working unless I put a reference to all libs my app use:

// myapp/tsconfig.json
{
    "extends": "../../tsconfig.base.json",
    "compilerOptions": {
        "types": ["node", "jest"]
    },
    "include": ["**/*.ts"],
    "references": [
        {
            "path": "./tsconfig.app.json"
        }
    ]
}

// myapp/tsconfig.app.json
{
    "extends": "./tsconfig.json",
    "compilerOptions": {
        "outDir": "../../dist/out-tsc",
        "emitDecoratorMetadata": true,
        "module": "commonjs",
        "target": "es2017",
        "types": ["node"]
    },
    "exclude": ["**/*.spec.ts"],
    "references": [
        {
            "path": "../../libs/lib1/tsconfig.json"
        },
        // <-- ... long list of libs refrence
    ]
}

without referencing libs tsconfig.json I got this error

TS6307: File '...../libs/lib1/src/lib/some-file.ts' is not listed within the file list of project '...../apps/myapp/tsconfig.app.json'. Projects must list all files or use an 'include' pattern.

@zhangciwu Is this how it should be?

@zhangciwu
Copy link

zhangciwu commented Jan 15, 2021

@AliYusuf95 I put all the lib path config in root tsconfig, and using paths instead of references

"paths": {
      "@myproject/testlib": ["libs/testlib/src/index.ts"],
}

Also I have blank include in myapp/tsconfig.json, and declare the include and exclude in myapp/tsconfig.app.json and myapp/tsconfig.spec.json

@KeKs0r
Copy link
Contributor

KeKs0r commented Mar 23, 2021

@AliYusuf95 : unfortunately not. There was a chain of TS issues I ran into and could not resolve them.

@craigbilner
Copy link

I created this executor which worked for my use case and then you can run standard commands such as nx run-many --target=tsc --all --parallel

@JakeGinnivan
Copy link
Contributor Author

I wrote up a blog post on how we are using TypeScript project references with NX at https://jakeginnivan.medium.com/using-typescript-project-references-in-nx-b3462b2fe6d4

The tl;dr of it is:

  • We no longer use nrwl's app plugins
  • We use esbuild/vite for building everything, these resolve files via path mappings so no type checking/tsc within our application/test/lint tool chains
  • tsc -b in the root of the project type checks everything
  • VSCode is configured to not map files back to source, so we run tsc -b --watch in our editor as a background task to get continual & incremental type checking and keep the editor errors up to date.

@developer239
Copy link

developer239 commented Aug 7, 2021

@JakeGinnivan that looks nice but I am not sure if the solution is to not use nrwl's app plugins. 😅 Although I totally understand that this may take months to be resolved...


I know this is open source and everything but do people really use in production something that doesn't tell them typescript errors by default? We can always write our own solution but that kind of kills the point of "standardization". 🙂 I focus on code quality and this is a major blocker for me.

Every project should have:

  • eslint
  • prettier
  • stylelint (if FE application)
  • git hooks (lint-staged, husky and commit lint)
  • easy type checking (ignoring an error now and then can easily make the project have hundreds of issues later)

otherwise it should never make it to production. 🙉

@developer239
Copy link

I created this executor which worked for my use case and then you can run standard commands such as nx run-many --target=tsc --all --parallel

This looks like a good solution although looking at the documentation the executor needs more than 1 file to actually work. 🤔

@JakeGinnivan
Copy link
Contributor Author

@developer239 I agree with the standardization and minimum quality bar, which is why we created our own plugin set.

The goal for us is to only type check once, not multiple times and also get a great editor and developer experience. The advantage of our approach is not only do we only type check once, we get full support for incremental compilation with TypeScript project references so the incremental compilation is really fast so we get super quick type checking feedback in our editors as we are developing.

Another advantage of us creating a new set of plugins is that the nrwl team can check out the different approach rather than any discussions just being based on theory.

@developer239
Copy link

developer239 commented Aug 8, 2021

@JakeGinnivan My post was more like a rhetorical question to the maintainers of this project. I totally understand why you decided to use your own solution. 🙌

@JakeGinnivan
Copy link
Contributor Author

@developer239 totally, I hope that they a look at my solution and consider it for a way forward

@stephenlaughton
Copy link

I wrote up a blog post on how we are using TypeScript project references with NX at https://jakeginnivan.medium.com/using-typescript-project-references-in-nx-b3462b2fe6d4

The tl;dr of it is:

  • We no longer use nrwl's app plugins
  • We use esbuild/vite for building everything, these resolve files via path mappings so no type checking/tsc within our application/test/lint tool chains
  • tsc -b in the root of the project type checks everything
  • VSCode is configured to not map files back to source, so we run tsc -b --watch in our editor as a background task to get continual & incremental type checking and keep the editor errors up to date.

@JakeGinnivan awesome work! i've been looking at your plugin and method as a starting point for a similar approach in our monorepo. one question, when you say:

VSCode is configured to not map files back to source, so we run tsc -b --watch in our editor as a background task to get continual & incremental type checking and keep the editor errors up to date.

could you elaborate on how you configured VSCode? i am not super familiar with running background tasks and how to make sure VSCode is using the tsc -b --watch command instead of spawning its own typescript server.

tsc -b in the root of the project type checks everything

is working great and is really 🔥

@JakeGinnivan
Copy link
Contributor Author

could you elaborate on how you configured VSCode? i am not super familiar with running background tasks and how to make sure VSCode is using the tsc -b --watch command instead of spawning its own typescript server.

For sure, the language service only really picks up issues of open files, but it also provides intellisense and such so the approach doesn't replace it, it just augments it.

This is my .vscode/tasks.json, I can cmd+shift+b when I open the repo to start the build incrementally in the background, it also surfaces build errors into the Problems panel of vscode.

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "typescript",
            "tsconfig": "tsconfig.json",
            "option": "watch",
            "problemMatcher": ["$tsc-watch"],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "label": "tsc: watch - tsconfig.json"
        }
    ]
}

@always-maap
Copy link

@JakeGinnivan
We wrote an internal executor for our company and added it to every app and lib in workspace. Something like this <333

import { ExecutorContext } from '@nrwl/devkit';
import { detectPackageManager } from '@nrwl/tao/src/shared/package-manager';
import { spawn } from 'child_process';

export default async function tscExecutor(_, context: ExecutorContext) {
  const packageManager = detectPackageManager();
  const packageManagerCmd = packageManager === 'pnpm' ? 'pnpx' : packageManager === 'yarn' ? 'yarn' : 'npx';

  const libRoot = context.workspace.projects[context.projectName].root;

  const executionCode = await new Promise((resolve) => {
    const child = spawn(packageManagerCmd, ['tsc', '-p', libRoot, '--noEmit'], { stdio: 'inherit' });
    child.on('data', (args) => console.log(args));
    child.on('close', (code) => resolve(code));
  });

  return { success: executionCode === 0 };
}

@petrkrejcik
Copy link

@JakeGinnivan We wrote an internal executor for our company and added it to every app and lib in workspace. Something like this <333

import { ExecutorContext } from '@nrwl/devkit';
import { detectPackageManager } from '@nrwl/tao/src/shared/package-manager';
import { spawn } from 'child_process';

export default async function tscExecutor(_, context: ExecutorContext) {
  const packageManager = detectPackageManager();
  const packageManagerCmd = packageManager === 'pnpm' ? 'pnpx' : packageManager === 'yarn' ? 'yarn' : 'npx';

  const libRoot = context.workspace.projects[context.projectName].root;

  const executionCode = await new Promise((resolve) => {
    const child = spawn(packageManagerCmd, ['tsc', '-p', libRoot, '--noEmit'], { stdio: 'inherit' });
    child.on('data', (args) => console.log(args));
    child.on('close', (code) => resolve(code));
  });

  return { success: executionCode === 0 };
}

I'm trying to replicate your executor but when I run nx run node:tsCheck I get error:

Cannot use import statement outside a module

Do you how to solve it?
I've uploaded the repo here: https://github.com/petrkrejcik/nx-test

@always-maap
Copy link

@JakeGinnivan We wrote an internal executor for our company and added it to every app and lib in workspace. Something like this <333

import { ExecutorContext } from '@nrwl/devkit';
import { detectPackageManager } from '@nrwl/tao/src/shared/package-manager';
import { spawn } from 'child_process';

export default async function tscExecutor(_, context: ExecutorContext) {
  const packageManager = detectPackageManager();
  const packageManagerCmd = packageManager === 'pnpm' ? 'pnpx' : packageManager === 'yarn' ? 'yarn' : 'npx';

  const libRoot = context.workspace.projects[context.projectName].root;

  const executionCode = await new Promise((resolve) => {
    const child = spawn(packageManagerCmd, ['tsc', '-p', libRoot, '--noEmit'], { stdio: 'inherit' });
    child.on('data', (args) => console.log(args));
    child.on('close', (code) => resolve(code));
  });

  return { success: executionCode === 0 };
}

I'm trying to replicate your executor but when I run nx run node:tsCheck I get error:

Cannot use import statement outside a module

Do you how to solve it? I've uploaded the repo here: https://github.com/petrkrejcik/nx-test

I did not test your code but I think "implementation": "./tsCheck". you need to use js as impl.

@petrkrejcik
Copy link

@JakeGinnivan

I did not test your code but I think "implementation": "./tsCheck". you need to use js as impl.

Oh yeah, it was that, thank you!

Do you know if there is something else that I need to setup (except the steps in the docs for building custom executors)? Currently the command doesn't throw any error but if I run tsc agains one specific file the error is thrown correctly.

image

@always-maap
Copy link

always-maap commented Dec 1, 2021

@JakeGinnivan

I did not test your code but I think "implementation": "./tsCheck". you need to use js as impl.

Oh yeah, it was that, thank you!

Do you know if there is something else that I need to setup (except the steps in the docs for building custom executors)? Currently the command doesn't throw any error but if I run tsc agains one specific file the error is thrown correctly.

change this line in your impl.ts and build ts file again
const child = spawn(packageManagerCmd, ['tsc', '-b', libRoot], {

@petrkrejcik
Copy link

@JakeGinnivan Again - thank you 👍

For anybody interested: this is a repo with working command tsCheck- https://github.com/petrkrejcik/nx-test
Steps to add it to your monorepo:

  1. Copy tools/executors/tsCheck
  2. Add to your workspace.json to all desired projects:
{
  "targets": {
    "tsCheck": {
      "executor": "./tools/executors/tsCheck:tsCheck"
    }
  }
}
  1. Run nx run <appName>:tsCheck

@dobromyslov
Copy link

For Windows users a slight fix is needed. Add shell: true to the spawn options. Without this option Windows expects "npx.cmd" instead of "npx".

import { ExecutorContext } from '@nrwl/devkit';
import { detectPackageManager } from '@nrwl/tao/src/shared/package-manager';
import { spawn } from 'child_process';

export default async function tscExecutor(_, context: ExecutorContext) {
  const packageManager = detectPackageManager();
  const packageManagerCmd = packageManager === 'pnpm' ? 'pnpx' : packageManager === 'yarn' ? 'yarn' : 'npx';

  const libRoot = context.workspace.projects[context.projectName].root;

  const executionCode = await new Promise((resolve) => {
    const child = spawn(packageManagerCmd, ['tsc', '-p', libRoot, '--noEmit'], { 
        stdio: 'inherit',
        shell: true // Windows fix "Error: spawn npx ENOENT"
    });
    child.on('data', (args) => console.log(args));
    child.on('close', (code) => resolve(code));
  });

  return { success: executionCode === 0 };
}

@istvandesign
Copy link

istvandesign commented Feb 28, 2022

On my side something is off, when running the upper executor on a project it will detect assets like .svg's as errors ' Cannot find module './icons/trash.svg' or its corresponding type declarations. It will also complain inside the shared components we have outside the project.

The upper script will use the tsconfig from a specific project even for the shared stuff across the repo, I am not yet sure how to fix this, but in the IDE (VSCode) I don't seem to have the same issues.

@webpro
Copy link

webpro commented Aug 23, 2022

Since I've found the solution here and implemented it in our project, I thought I might just as well push and publish it: https://github.com/webpro/nx-tsc. This will only type-check using --noEmit and -p with the provided tsConfig.

tl/dr;

npm install -D @webpro/nx-tsc
{
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "sourceRoot": "libs/my-lib/src",
  "targets": {
    "tsc": {
      "executor": "@webpro/nx-tsc:tsc",
      "options": {
        "tsConfig": ["tsconfig.json"]
      }
    }
  }
}
nx tsc my-lib

Thanks, and maybe it's useful to someone. Feel free to file any issues/questions in the GH repo.

@goldylucks
Copy link

@webpro this works but doesn't output the errors to the terminal when doing nx run-many --target=tsc. Any idea how to achieve that?

@webpro
Copy link

webpro commented Sep 2, 2022

@webpro this works but doesn't output the errors to the terminal when doing nx run-many --target=tsc. Any idea how to achieve that?

The current solution uses spawn for performance reasons, I think exec would handle this better.

@capJavert
Copy link

capJavert commented Sep 14, 2022

You can also do this without additional libraries with nx:run-commands executor:

{
    "$schema": "../../node_modules/nx/schemas/project-schema.json",
    "sourceRoot": "libs/my-lib/src",
    "targets": {
        "tsc": {
            "executor": "nx:run-commands",
            "options": {
                "commands": [
                    {
                        "command": "tsc --noEmit -p libs/my-lib/tsconfig.json"
                    }
                ]
            }
        }
    }
}

@peter-wd-1
Copy link

peter-wd-1 commented Oct 9, 2022

You can also do this without additional libraries with nx:run-commands executor:

{
    "$schema": "../../node_modules/nx/schemas/project-schema.json",
    "sourceRoot": "libs/my-lib/src",
    "targets": {
        "tsc": {
            "executor": "nx:run-commands",
            "options": {
                "commands": [
                    {
                        "command": "tsc --noEmit -p libs/my-lib/tsconfig.json"
                    }
                ]
            }
        }
    }
}

This solution works for me as well and I have generator that add this command to project.json. But I use libs/my-lib/tsconfig.lib.json instead of libs/my-lib/tsconfig.json for the path to tsconfig.

@webpro
Copy link

webpro commented Oct 9, 2022

Didn't measure the difference, but wanted to eliminate anything I could since spawning + running tsc for every Nx project is "expensive", and the config with the plugin is slightly less verbose. But totally understand the simplicity and advantage of not having to include yet another dependency. It would really help if tsc allowed multiple -p arguments (which it silently ignores).

@silouanwright
Copy link

silouanwright commented Nov 23, 2022

@webpro your plugin works great! I'm going to replace our custom commands with it. Would you say this is more performant than running the command directly, when running check-types on multiple projects?

As far as the whole "it's another dependency" caveat... I don't place too much stock in that. The whole entire approach with executors in Nx has you downloading another dependency, for the purpose of standardization, simplification, etc. There's a lot of benefits of these things being in another dependency as well, because if you're in a big company, someone may be tempted to sneak some flag or custom config into one of the projects, because the executor is for custom commands. So it being a dependency is to an extent, a plus for me. It ensures this will stay simple & standard across packages. Granted, having official support would be nice, but this is the next best thing.

Thanks for making it 🙌

@sebastienjust
Copy link

@webpro using your plugin too. Works great, thank you ! 👏

Usage that works in my project :

Followed instructions in @webpro/nx-tsc plugin page.
Added target to each project's project.json (be careful to add every required .tsconfig file that applies to the project

"targets": {
"tsc": {
      "executor": "@webpro/nx-tsc:tsc",
      "options": {
        "tsConfig": ["tsconfig.app.json", "tsconfig.spec.json"]
      }
    },
}

Then added as an npm script in package.json to check everything

"scripts": {
    "tsc": "nx run-many --target=tsc --all=true --verbose",
  },

Added as a custom build task in VSCode's .vscode/tasks.json using $tsc problem matcher

"tasks": [
    {
      "type": "npm",
      "script": "tsc",
      "group": "build",
      "problemMatcher": [
        "$tsc"
      ],
      "label": "npm: tsc",
      "detail": "Checks all typescript projects and report problems to VSCode"
    }
  ]

The --verbose flag is not required for VSCode (VSCode catches the intermediate outputs of NX and give them to $tsc problem matcher) but required when used in the command-line, or else you won't be able to see the problematic files and line numbers.

In my opinion, this kind of feature should be built-in in NX. Builds must fail if there are problems in typings and not be shipped in production (like we do in every other typed language).

@joshribakoff-sm
Copy link

joshribakoff-sm commented Jan 31, 2023

Didn't measure the difference, but wanted to eliminate anything I could since spawning + running tsc for every Nx project is "expensive"
Would you say this is more performant than running the command directly, when running check-types on multiple projects?

I don't think so. In both cases you're spawning one process per each project you type check, the only difference is the verbosity of the configuration.

Note, adding this new Nx target may have some overlap with the type checking already being done in the build target. To make Nx more like other frameworks, my proposal would be for the Nx plugins to make build purely invoke babel, and do no type checking whatsoever. Separately, the Nx plugins should add a new test target that strictly type checks all files in that project. This would be a breaking change, but really does seem like table stakes.

I think vite, etc. seems like a potential distraction. Really the "ask" here is for build to use babel (no type checking) instead of ts-loader (has type checking, but is flawed), and separately surface a new tsc --noEmit target that strictly uses tsc to perform type checking (avoiding the flaws in the ts-loader approach).

Alternatively, babel-jest could be replaced with ts-jest which does type check the tests as it executes them, but again that is "flawed" and it would far more preferable [I think] to have an explicit tsc --noEmit target. This would afford users flexibility to do things like only run unit tests after the type checking completes without errors, and doesn't hide errors in files that happen to not be imported via an entry point. ts-jest also has performance problems, for me, making it a "no go".

In the meantime the workaround is pretty simple, just add somewhat redundant targets to your project.json:

"typecheck": {
      "executor": "@nrwl/workspace:run-commands",
      "options": {
        "commands": ["yarn tsc -p apps/app/tsconfig.spec.json --noEmit", "yarn tsc -p apps/app/tsconfig.app.json --noEmit"]
      }
    },

The few seconds of redundant CPU cycles is not worth hours of your time fixing bugs months later. It would be nice if nx could update the build target to fix the redundancy, though, and save us the boilerplate.

@vemundeldegard
Copy link

I recently added targets to our projects to perform type checking. I wanted to create a reusable executor, instead of creating the redundant targets. This way if I need to make a change to the command, I can make sure it is the same for all. Here is what I have:

import { TypesExecutorSchema } from './schema';
import { ExecutorContext } from '@nrwl/devkit';
import * as core from '@nx-tools/core';

export default async function runExecutor(options: TypesExecutorSchema, context: ExecutorContext) {
  if (!context.workspace || !context.projectName) return;

  const { tsConfig } = options;

  const output = await core.getExecOutput(`yarn tsc --project ${tsConfig} --noEmit true`);

  const success = output.exitCode === 0;

  return { success };
}

You are talking about a few seconds of redundant CPU cycles @joshribakoff-sm, but in my experience the run time for my type checking target is around 13 minutes for 168 small projects in my workspace when running in our Github Workflow. Locally it only takes 2 minutes. Caching the target helps in many cases, and affected also helps, but 13 minutes is stealing a lot of our run minutes. Are we doing something wrong?

@joshribakoff-sm
Copy link

joshribakoff-sm commented Mar 28, 2023

type checking target is around 13 minutes for 168 small projects in my workspace when running in our Github Workflow. Locally it only takes 2 minutes.

Seems unrelated to this thread. Maybe try increasing the resources for your CI machines.

You are talking about a few seconds of redundant CPU cycles @joshribakoff-sm

Personally, I would rather wait 13 minutes or however long, rather than letting bugs slip through, but that's just my thought process and I'm not suggesting everyone should do it the same way :) If skipping type checking is desirable, that's a valid choice to make but not the choice I like to make.

Here is what I have:

Interesting, I'm curious if it surfaces the logs, or just the exit code - looks pretty nice though!

@webpro
Copy link

webpro commented Mar 28, 2023

The performance of things is indeed not really what this issue is about, but part of the solution is to prevent doing things. In a recent project half of the Nx projects consisted of Next.js applications. So for such cases where you build applications and they're type-checked in such a process as well, try not to type-check the app/lib twice.

@unrealsolver
Copy link
Contributor

This command works for me pretty well:

    "typecheck": {
      "executor": "nx:run-commands",
      "options": {
        "cwd": "packages/your-pkg-name",
        "commands": ["tsc -p tsconfig.lib.json --noEmit"],
        "forwardAllArgs": false,
        "description": "Type check with tsc"
      }
    }

@FrozenPandaz
Copy link
Collaborator

@leosvelperez is working on something in this area. Stay tuned.

@Ccry11
Copy link

Ccry11 commented Jul 26, 2024

Hi everyone, Is there any update on this?
It's pretty time consuming to add the tsc target on every library

@ianldgs
Copy link
Contributor

ianldgs commented Jul 26, 2024

Hi everyone, Is there any update on this?
It's pretty time consuming to add the tsc target on every library

Maybe create your own generator?
Seems unlikely that this will be implemented...

@Ccry11
Copy link

Ccry11 commented Jul 26, 2024

Maybe create your own generator? Seems unlikely that this will be implemented...

I hoped that there was an easier way of doing this since typechecking should be one of the basic features in a build system tool like NX.
Inferred Tasks for linting is available and it's a great feature. I don't understand why the same thing is not available for type checking.

It's also important to note that a generator can only partially fix the issue because you don't have to manually add the target when you create a library but you will still have a huge amount of duplicated config code for the type cheking generator in your entire workspace

@Shuunen
Copy link

Shuunen commented Jul 29, 2024

This command works for me pretty well:

    "typecheck": {
      "executor": "nx:run-commands",
      "options": {
        "cwd": "packages/your-pkg-name",
        "commands": ["tsc -p tsconfig.lib.json --noEmit"],
        "forwardAllArgs": false,
        "description": "Type check with tsc"
      }
    }

works nicely , can't we use a placeholder here "cwd": "packages/your-pkg-name" like "cwd": "{currentDir}" or something ?

@lukeramsden
Copy link

I wanted to try and create a local plugin that would infer these typechecking tasks for any project with a tsconfig.json, but trying to understand how to do that when the only option is essentially reading the vite/jest plugins which already do this and trying to figure out what APIs they're using are even public at all has put it a bit beyond me at the moment. Has anyone else attempted this?

@endurance-chorus
Copy link

What is the current status on this?

@leosvelperez is working on something in this area. Stay tuned.

Has something been released already or should we roll our own for now?

@Shuunen
Copy link

Shuunen commented Sep 18, 2024

Since the last update I got a bulitin typecheck task :

image

Works great, I removed my custom task

@danreeves
Copy link

@Shuunen is that something you can open source?

@Shuunen
Copy link

Shuunen commented Sep 18, 2024

I did nothing ^^ it's comming from the nx/vite plugin 😸

@Ccry11
Copy link

Ccry11 commented Sep 24, 2024

I have noticed that the new :typecheck task available in the vite plugin uses the tsc --noEmit -p tsconfig.app.json on the app libs.
On my project this causes a lot of typescript errors but if I remove the "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] line in the tsconfig.app.json those errors are not displayed anymore.

Are you sure that the tsc command should use the tsconfig.app.json? In my opinion it should use the tsconfig.json.

For example, in the custom executor I made I check the libType:

        'tsc',
        '--noEmit',
        '-p',
        join(
          libRoot,
          libType === 'application' ? 'tsconfig.json' : 'tsconfig.lib.json'
        ),

@thdk
Copy link
Contributor

thdk commented Sep 26, 2024

I see the following target inferred for my project:

image

Which indicates I should be able to pass any flag from tsc as options for the typecheck target.

However, adding project like:

    "typecheck": {
      "options": {
        "project": "tsconfig.json"
      }
    },

gives:

> nx run web:typecheck

> tsc --noEmit -p tsconfig.app.json --project=tsconfig.json

error TS5023: Unknown compiler option '--project=tsconfig.json'.
Warning: command "tsc --noEmit -p tsconfig.app.json --project=tsconfig.json" exited with non-zero status code

@ryan-mcginty-alation
Copy link

Any way to make typecheck also run checks for spec / test / storybook files that use separate tsconfig files?

@Sebastian-G
Copy link

@ryan-mcginty-alation You can do something like this...

 {
// ...
    "typecheck": {
      "executor": "nx:noop",
      "dependsOn": ["typecheck-app", "typecheck-spec", "typecheck-storybook"]
    },
    "typecheck-app": {
      "executor": "nx:run-commands",
      "options": {
        "command": "tsc --noEmit -p {projectRoot}/tsconfig.app.json"
      }
    },
    "typecheck-spec": {
      "executor": "nx:run-commands",
      "options": {
        "command": "tsc --noEmit -p {projectRoot}/tsconfig.spec.json"
      }
    },
    "typecheck-storybook": {
      "executor": "nx:run-commands",
      "options": {
        "command": "tsc --noEmit -p {projectRoot}/tsconfig.storybook.json"
      }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests