-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Incremental --build, then delete generated js file, then another incremental --build does not recreate js file #30602
Comments
Hmm the root cause of this is that in general our incremental build (BuilderProgram) isn't equipped to deal with missing output file as indication to build but changed file as more like it. Need to think about what we can do here. Till then the workaround is to run --clean and then build or add comment or something into the file whose output needs to be generated. |
A separate, but possibly related issue: deleting source |
@irakliy81 that's totally out of scope and does not work even without --incremental. Build cannot delete any output file unless you specify clean (which will also delete output files of config specified at that moment) |
👍 |
@sheetalkamat - yes, I wouldn't expect it to work without --incremental flag since in that case there is no info stored about the previous build. But with the --incremental flag, it should be possible to remove output files if the source files have been removed. A separate question: how do you specify |
@irakliy81 |
@milesj - thanks! But it doesn't seem to be listed here: https://www.typescriptlang.org/docs/handbook/compiler-options.html and if I try to set it in VS Code I get "unknown compiler option" error. Am I missing something? |
It's part of project references. Not sure if it's available outside of that, nor as a compiler option. https://www.typescriptlang.org/docs/handbook/project-references.html |
any plans on fixing this? cc @sheetalkamat it kills the point of caching build info in CI |
For clarity: What/who is deleting the output files and why? |
There are multiple workarounds for this issue.
Its not clear why only .js file is deleted |
I’ve had this happen when an unrelated |
Your expectations are fine, we're just trying to figure out if the scenario is common enough that e.g. people who have 1,200 build outputs should be paying the cost on every single operation for TS to check if all those outputs still exist. Can the "unrelated clean script" just delete the |
Well yes, we should check files existence on our side in CI. Which is fine, but as already mentioned, it's against expectations. Also, if only 1 file is deleted accidentally, deleting whole buildinfo file is a bit overkill |
I've noticed also |
tsbuildinfo also does not get invalidated when tsconfig.json changes. Thus code generated e.g with |
@matthiasg See #31118. |
This is reasonable, but I think the 90% case is worth covering here: something like if Another workaround / fix for people who need these external tools is to simply place the |
killing the whole purpose here |
The Is it fair to assume that the TS compiler will/could generate the output faster when it has a If the build time is going to be the same as a fully clean one with no |
Here is an usecase when incremental build breaks developer experience: We have a file that reads all A/B experiment configuration files (*.ts) from folder using glob. When developer deletes experiment file.ts they expect compiled file to be removed too, otherwise A/B test stays active. Only manually checking and deleting build info helps. Hope it’s clear. |
Any news on a fix? |
I so much agree with @simonbuchan
I just lost 1 hour with that. Adopted new "project" strategy (for a src + test simple project); built; cleaned the whole dist; wondered half an hour why subsequent |
I would have assumed that In the current state there's basically a secret contract saying that nobody but tsc can touch the build output. It's not what I would assume from something simply advertised as an incremental build. And apart from subtle phrasing in the 3.4 release notes I don't think it's clear from the docs either that only types definitions are checked. I too would be for making |
I enabled |
This is a bit confusing.
It's just not intuitive. I think many people spend many hours (if not days) fiddling around with this stuff. It is too time consuming. |
Experience report: We are running into this in the context of converting one project in a monorepo from JS to TS. So we used to have an I saw a couple of colleagues complaining in Slack and was affected myself, so I guess that more colleagues were affected but didn't complain. I estimate we lost about 10 person hours because of this, plus some confidence in typescript. (Personally I'm still confident in typescript, but some colleagues had a first bad interaction now). |
We are having problems similar to @Toxaris I have also tried looking into the |
Yes, yes please. In our use case we compile migration files to a directory and all files in this directory are evaluated when the migrations run. We have had issues where checking out to feature branch A, testing the feature, reverting the migrations and checking out to feature B, preserves the migrations of feature A. This harms developer experience because our developers need to keep track of any compiled files that might linger from other branches. IMO an incremental build should take the output folder from the current state to the desired state while using |
For "should a subsequent built delete files that were generated by a prior build but no longer have a source?", #16057 is closely related (with several links to libs that patch in this behavior). |
I strongly agree with this statement! At the moment, incremental builds provide maximum performance but with the possibility of "incorrect" or unexpected output (i.e., it does not build a file we expected it to build). I'd rather the incremental build always be 100% correct. It should still be faster than a full clean and build, since it can skip the compilation of some modules. Maybe we need a different flag that guarantees correctness, but with a slight performance penalty?
|
Safety should be opt-out, not opt-in. |
I agree, but since this issue has been open 2 years, I was hoping to suggest something that might be accepted, so those of us who care can use the safer option. Ideally, the
The default values were chosen because they are safest:
|
I just got hit by an issue from a renamed source file, where the old output JS file ended up getting executed instead, and had a runtime error. I think my case was specifically the I'm a fan of having configuration options for correctness / speed tradeoffs if possible. It sounds like there's multiple ways for the compiled output directory to get out of sync with the source, where incremental builds won't re-sync. This makes incremental builds less valuable for me, by not being able to trust whether the output directory is in the expected state or requires some manual inspection / fixing. My understanding of some current workaround options are: I'm curious if there's any other good workarounds! Regarding precedents for deletion, I'm familiar with some related config flags in a couple other tools.
|
Hi,
IMPORTANT: NestJS set this "incremental" property to "true" by default in every new NestJS project. This is how I got the problem. For several days I got no problem: the "tsconfig.tsbuildinfo" file was generated inside the "dist" folder. But at a certain moment, I should have set a bad config because I did several configuration tests, and the "tsconfig.tsbuildinfo" has been generated in the main folder of the project as in the above example, causing the problem. The only bypass I see:
Typescript version: 4.8.2 Regards. |
My use case for having the e.g. {
"scripts": {
"clean": "rm -rf dist",
"build": "npm run clean && npm run build:js && npm run build:types && npm run build:files",
"build:js": "swc src --outdir dist",
"build:types": "tsc --declaration --emitDeclarationOnly",
"build:files": "cpx src dist --ignore *.ts"
}
} The reason I would like to clean between builds is because files might have been deleted since the last build and not removing them increases the size of the build artifact, is confusing to debug and can result in unexpected consequences during execution - e.g. move I was hoping that Similar to other posters it took me a while to understand what was happening and finally end up here 😄 |
One scenario in which output files may be removed is when publishing a package that uses And since |
I'm seeing similar behavior when running a build doesn't output a new build (I use incremental as well). Deleting the tsbuildinfo does fix this. However I found that the issue I had was using "emitDecoratorMetadata" in the tsconfig for our decorators. This for some reason prevents 'build' from re-generating the build output correctly. |
TypeScript Version: 3.4.0-dev.20190326
Search Terms:
incremental
Code
tsconfig.json:
x.ts:
Expected behavior:
$ tsc --build
x.js
has been generated$ rm x.js
$ tsc --build
Expected: x.js has been regenerated
Actual behavior:
x.js still does not exist
Related Issues:
Did not find any.
The text was updated successfully, but these errors were encountered: