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

.tsbuildinfo file should be created when the noEmit flag is enabled #30661

Closed
vkrol opened this issue Mar 30, 2019 · 24 comments · Fixed by #39122
Closed

.tsbuildinfo file should be created when the noEmit flag is enabled #30661

vkrol opened this issue Mar 30, 2019 · 24 comments · Fixed by #39122
Assignees
Labels
Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Milestone

Comments

@vkrol
Copy link

vkrol commented Mar 30, 2019

TypeScript Version: 3.4.0-dev.20190330

Search Terms: incremental, noEmit, no emit, tsbuildinfo

Code:
https://github.com/vkrol/typescript-incremental-no-emit

{
  "compilerOptions": {
    "outDir": "./dist",
    "incremental": true,
    "noEmit": true
  }
}

Expected behavior:
.tsbuildinfo file should be created when the noEmit flag is enabled.

Actual behavior:
.tsbuildinfo file is not created when the noEmit flag is enabled.

@vkrol vkrol changed the title .tsbuildinfo file should be created when the noEmit flag is enabled. .tsbuildinfo file should be created when the noEmit flag is enabled Mar 30, 2019
@OliverJAsh
Copy link
Contributor

This would be useful so we can still benefit from fast rebuilds when using tsc for type checking only.

@sheetalkamat
Copy link
Member

Though emitting a file (in this case .tsbuildinfo) when --noEmit is specified seems inappropriate.
cc: @DanielRosenwasser and @RyanCavanaugh for their input.

@denis-sokolov
Copy link

The way I use these terms, “emit” refers to the valuable output of the application, something we’d put to stdout in unix terms. The tsbuildinfo file is a cache that is supposed to be invisible to the consumer. The fact that it happens to be a file that we happen to write to disk is rather an irrelevant implementation detail.

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Apr 1, 2019

"tsc emits anything when --noEmit is specified" is a follow-up bug report to this one.

The problem here is that incremental is on by default if composite is on, so this is an actual risky change because it's going to mean new build artifacts in unexpected places for people using --noEmit today.

If the build info file path is specified manually, then writing it out does seem OK

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Experience Enhancement Noncontroversial enhancements labels Apr 1, 2019
@denis-sokolov
Copy link

denis-sokolov commented Apr 1, 2019

It tsbuildinfo a build artifact in an unexpected place, though? What if we write this cache to /tmp, the Windows registry, or whatever other storage, as long as the user does not see it? (edit: to be clear, the previous sentence is a hypothetical to help identify the meaning of tsbuildinfo, not a real suggestion) It seems like the explicitly thorough solution would be to split the noEmit option into typecheckButNoBuildOutput and noTouchingMyFilesystem.

@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Apr 1, 2019
@vkrol
Copy link
Author

vkrol commented Apr 2, 2019

If the build info file path is specified manually, then writing it out does seem OK

Good idea 👍

olmobrutall referenced this issue in signumsoftware/framework Apr 2, 2019
@fmal
Copy link

fmal commented Apr 4, 2019

@RyanCavanaugh

If the build info file path is specified manually, then writing it out does seem OK

i second this!

@META-DREAMER
Copy link

This would be incredibly useful in react native since the typescript code is parsed with the packager using Babel 7 so for type checking we have to use tsc --noEmit

@oleg-codaio
Copy link

I was looking into just ditching the --noEmit flag in order to use --incremental, but even though the subsequent build times decreased by half, the initial build time went up by quite a bit due to emit time.

image

I'm not super familiar with the implementation, but it seems like type checking via --noEmit should still be able to benefit from the signatures/dependencies stored in the build info cache file, and this would be great for use cases like speeding up type checking in CI by caching and reusing the build file periodically.

@zen0wu
Copy link

zen0wu commented Jun 1, 2019

+1. I'm temporarily setting outDir to a phantom folder just in order to the tsconfig.buildinfo emitted to speed up the compilation!

Context: It's a frontend project with webpack+babel so emitting js is not useful.

@chibicode
Copy link

+1 for outputting .tsbuildinfo if .tsBuildInfoFile is specified even when noEmit is true. I'm using TypeScript with Next.js, which uses noEmit: true and this change would be very helpful.

@guillaume86
Copy link

If the current implementation do not require the normal build output to work, could you add a forceEmitBuildInfo boolean to the compile options please? That will not change anything for people relying on the current behavior that way.

@ahem
Copy link

ahem commented Aug 14, 2019

+1 for support for this in some way. I am using Typescript with @babel/preset-typescript (which I assume will be a more and more common use) and that requires emit: false.

@alangpierce
Copy link
Contributor

alangpierce commented Aug 29, 2019

Like others, my team wants tsc to be usable as a typechecker rather than doing typecheck and transpile/build/emit at the same time. We have a few different build system configurations (webpack, ts-node/sucrase, and gulp), all of which skip typecheck, and none of them directly invoke tsc to emit JS, and typechecking is run alongside our linters in CI and development. Really, I think ideally tsc would be split into two different tools since checking and emit serve very different roles in our tooling and are run in different places, never at the same time. (This requires isolatedModules, of course.)

For now, sending the JS output to a dummy folder is the best option I could find to use tsc incrementally just for typechecking (on Mac):

tsc --project . --incremental --tsBuildInfoFile './.tsbuildinfo' --outDir /tmp/tsc-output

It's a bit slower for the first run, but not dramatically slower like #30661 (comment) was mentioning. The previous typecheck time with --noEmit was 40 seconds, and this new config is 50 seconds for the first run and 7 seconds for subsequent runs. It would be great to see this use case officially supported without the hack of running emit and directing output to a temp folder.

I also tried /dev/null as the outDir, which I think is a little faster but gives a lot of errors due to files not being writable.

rudolf added a commit to rudolf/kibana that referenced this issue Sep 27, 2019
Until microsoft/TypeScript#30661 is fixed we can't do incremental builds
with --noEmit so this sets an outDir for all typescript projects that
don't already have one.
pierrebeitz added a commit to dcos/dcos-ui that referenced this issue Dec 24, 2019
we enable the incremental-flag here.
because of the reasoning here
microsoft/TypeScript#30661, we need to also need to
emit stuff. we'll have an __out-dir until there's a better option.
pierrebeitz added a commit to dcos/dcos-ui that referenced this issue Dec 24, 2019
we enable the incremental-flag here.
because of the reasoning here
microsoft/TypeScript#30661, we need to also need to
emit stuff. we'll have an __out-dir until there's a better option.

we want to call tsc before running jest to not have to deal with tsc's output
regarding newly emitted files.
pierrebeitz added a commit to dcos/dcos-ui that referenced this issue Dec 24, 2019
we enable the incremental-flag here.
because of the reasoning here
microsoft/TypeScript#30661, we need to also need to
emit stuff. we'll have an __out-dir until there's a better option.

we want to call tsc before running jest to not have to deal with tsc's output
regarding newly emitted files.
pierrebeitz added a commit to dcos/dcos-ui that referenced this issue Dec 24, 2019
we enable the incremental-flag here.
because of the reasoning here
microsoft/TypeScript#30661, we need to also need to
emit stuff. we'll have an __out-dir until there's a better option.

we want to call tsc before running jest to not have to deal with tsc's output
regarding newly emitted files.
pierrebeitz added a commit to dcos/dcos-ui that referenced this issue Dec 24, 2019
we enable the incremental-flag here.
because of the reasoning here
microsoft/TypeScript#30661, we need to also need to
emit stuff. we'll have an __out-dir until there's a better option.

we want to call tsc before running jest to not have to deal with tsc's output
regarding newly emitted files.
@liana-p
Copy link

liana-p commented Mar 26, 2020

Just want to add to this, has any solution been reached for this issue? More and more people are switching to using babel to remove typescript and checking types with tsc on the side, but we then lose the advantage of incremental builds which isn't great.

@wincent
Copy link
Contributor

wincent commented May 17, 2020

So it seems that people who are using tsc just for type-checking (ie. with --noEmit) want to make it faster by being able to add --incremental as well.

I'd just like to point out that you can run into this problem from the other direction too: ie. you already have "incremental": true in your tsconfig.json (for speed), and you decide you want to be able to do a typecheck alone (ie. not write any output). Discovered this because my editor does a tsc --noEmit when you ask it to do a typecheck-only run.

Even if you wanted to forgo the speed benefits of "incremental": true for this use case, you can't turn it off temporarily because there is no --noIncremental (or analogous) flag. One workaround is to remove "incremental": true from your tsconfig.json and start passing --incremental only when you're doing an actual build and --noEmit when you just want to do a slow type check. As suggested above, setting a scratch outDir works too.

@InExtremaRes
Copy link

Even if you wanted to forgo the speed benefits of "incremental": true for this use case, you can't turn it off temporarily because there is no --noIncremental (or analogous) flag.

@wincent. There is no --noIncremental but you can pass --incremental false:

tsc --noEmit --incremental false

@wincent
Copy link
Contributor

wincent commented May 17, 2020

Thanks @InExtremaRes, that's easier than outDir.

@minedeljkovic
Copy link

@sheetalkamat is this also fixed in #39122 ?

@sheetalkamat
Copy link
Member

Yes

@sheetalkamat sheetalkamat self-assigned this Jun 26, 2020
@sheetalkamat sheetalkamat linked a pull request Jun 26, 2020 that will close this issue
@OliverJAsh
Copy link
Contributor

OliverJAsh commented Aug 10, 2020

I just upgraded to TS v4 to try this out. Previously we were just using noEmit, now we're using noEmit + incremental.

It seems that tsc is a lot slower when we run noEmit with incremental as opposed to without.

Stats from the diagnostics flag:

  • noEmit: 15s check time, 0s emit time
  • noEmit + incremental: 15s check time, 160s emit time

I'm assuming this is intended but does anyone understand why this is the case?

@sheetalkamat
Copy link
Member

@OliverJAsh Seems like declaration emit in your example takes longer. try tsc --d and you should see similar behavior. There are multiple issues tracking different declaration emit being slow and their workarounds that lookup and if something new, please create new issue with repro details.

@evelant
Copy link

evelant commented Aug 14, 2020

@sheetalkamat I also tried this out and it doesn't seem to create a tsbuildinfo file at all using Webstorm 2020.2 with noEmit incremental and tsBuildInfoFile set.

@oleg-codaio
Copy link

I wanted to propose a follow-up change to this: #40198

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.