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

TS Project build meta-output .tsbuildinfo emitted outside of outDir #43908

Closed
michkot opened this issue Apr 30, 2021 · 8 comments
Closed

TS Project build meta-output .tsbuildinfo emitted outside of outDir #43908

michkot opened this issue Apr 30, 2021 · 8 comments
Assignees
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@michkot
Copy link

michkot commented Apr 30, 2021

Bug Report

πŸ”Ž Search Terms

project build output directory
tsbuildinfo

πŸ•— Version & Regression Information

4.2.4
4.3.0-dev.20210430

⏯ Playground Link

N/A - problem with project builds

πŸ’» Code

Important bits of tsconfig files, all repository code is rooted at /drive-c/work/c:

// /drive-c/work/c/d/e/f/tsconfig.base.json
      "outDir": "build/tmp/", 
      "composite": true,

// /drive-c/work/c/d/e/f/tests/tsconfig.json - base case a)
  "extends": "../tsconfig.base.json",
    "rootDir": "../../../../i/j/k/l/",
    //"outDir" not specified
  "include": [
    "../../../../i/j/k/l/**/*",
  ],
// /drive-c/work/c/d/e/f/tests/tsconfig.json - case b)
    "outDir": "../build/tmp/tests/", 
// /drive-c/work/c/d/e/f/tests/tsconfig.json - case c)
    "outDir": "../build/tmp/tests/tests2/tests3/", 
// /drive-c/work/c/d/e/f/tests/tsconfig.json - case d)
    "outDir": "../../../build/tmp", 

πŸ™ Actual behavior

In case a) the file tsconfig.tsbuildinfo is emitted into
/drive-c/work/c/d/d/e/f/tests/tsconfig.tsbuildinfo

In case b) the file tsconfig.tsbuildinfo is emitted into
/drive-c/work/c/d/e/d/e/f/tests/tsconfig.tsbuildinfo

In case c) the file tsconfig.tsbuildinfo is emitted into
/drive-c/work/c/d/e/f/build/d/e/f/tests/tsconfig.tsbuildinfo

In case c) the file tsconfig.tsbuildinfo is emitted into
/drive-c/work/d/e/f/tests/tsconfig.tsbuildinfo

All these emit locations are wrong, are polluting my repository, and in case d) tsc emits files completely out of repository tree.

πŸ™‚ Expected behavior

In all the cases, tsconfig.tsbuildinfo is placed under $outDir/$name-of-project/$name-of-tsconfig.tsbuildinfo (or similar location under $outDir); in my case a):
/drive-c/work/c/d/e/f/build/tmp/tests/tsconfig.tsbuildinfo

Notes:

I have various requirements that force me to structure TS projects irrelevant of actual code organization. One of them being that it is not possible to have hand-written .d.ts files become part of (project) compilation output, something that's scattered over multiple issues here: #35296 #39231 #38146

@sheetalkamat
Copy link
Member

We need clear repro with project structure (including source file structure) showing the issue since the complete structure of project matters when determining where the tsbuildinfo goes.

@sheetalkamat sheetalkamat added the Needs More Info The issue still hasn't been fully clarified label Apr 30, 2021
@michkot
Copy link
Author

michkot commented May 3, 2021

We need clear repro with project structure (including source file structure) showing the issue since the complete structure of project matters when determining where the tsbuildinfo goes.

@sheetalkamat Here it is, I have created a minimal dummy project for reproduction of the behaviour I described above! πŸ˜ƒ
reproducible-example.zip

@sheetalkamat sheetalkamat removed the Needs More Info The issue still hasn't been fully clarified label May 3, 2021
@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label May 13, 2021
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.4.0 milestone May 13, 2021
@andrewbranch
Copy link
Member

It looks like this was done intentionally, at least to some degree, hereβ€”it’s even mentioned in the commit message:

if rootDir and outDir then outdir/relativePathOfConfigFromRootDir/configname.tsbuildinfo

Here’s a simplified repro:

// @Filename: /configs/a/tsconfig.json
{
  "compilerOptions": {
    "composite": true,
    "rootDir": "../../sources",
    "outDir": "out"
  },
  "include": ["../../sources"],
}

// @Filename: /sources/index.ts
export {}

The outDir is /configs/a/out, and that’s where index.js and index.d.ts get written. But using the formula for the .tsbuildinfo path, {outDir}/{relativePathOfConfigDirectoryFromRootDir}/{configBasename}.tsbuildinfo, we have

  • outDir = /configs/a/out
  • relativePathOfConfigDirectoryFromRootDir = ../configs/a
  • configBasename = tsconfig

so the result is /configs/a/out/../configs/a/tsconfig.tsbuildinfo, which resolves to /configs/a/configs/a/tsconfig.tsbuildinfo.

I’m guessing there is a general assumption that the relative path of a config file from its rootDir is always either straight up (../tsconfig.json) or straight down (./project-a/tsconfig.json). But I’m not sure exactly what the motivation is to not just put the .tsbuildinfo file in the outDir all the timeβ€”@sheetalkamat?

@andrewbranch andrewbranch added Bug A bug in TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. labels May 21, 2021
@sheetalkamat
Copy link
Member

sheetalkamat commented May 21, 2021

Always writing to outDir could cause issues with overwriting tsbuildinfo if two projects use same outDir and different rootDir structure to adjust where things go.. So it follows the logic similar to how output structure is computed and i think that is more sound. I this issue is working as intended and there is always workaround to specify tsbuildinfo location in your options if you really care about it.

@andrewbranch andrewbranch added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Bug A bug in TypeScript labels May 21, 2021
@typescript-bot
Copy link
Collaborator

This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@michkot
Copy link
Author

michkot commented May 23, 2021

Thanks for the investigation @sheetalkamat @andrewbranch, but let me strongly disagree on this being closed.

This option offers a way to configure the place where TypeScript keeps track of the files it stores on the disk to indicate a project’s build state β€” by default, they are in the same folder as your emitted JavaScript.

This creates a series of .tsbuildinfo files in the same folder as your compilation output.

  • the current default can pollute unrelated/unexpected folders with build output and makes change-monitoring (build systems) and cleanup of build outputs un-intuitive / error-prone
  • I'd even call the current behavior a consistency/security problem! The tsbuildinfo being not only emitted but also read out of the defined source / outDir directory tree means that TSC might read stuff that I do not control! Definitely not something I would call "more sound" :/

I would suggest that the right "sound" approach would be one/multiple of:

  • warn the user to set tsbuildinfo parameter when using incremental/composite switches in order to prevent his behaviour
  • adjust the docs and explain the choose-destination algorithm there (there = composte/incremental/tsBuildInfoFile)
  • by default, generate the tsconfig into outDir (or next to config when outDir=default) and emit and error if it would be overwritten be an unrelated project output (very breaking?)
  • keep the behavior as is, except when the tsbuildinfo would be generated outside of outDir - then issue an error (not so breaking, bot not nice either -> user might be surprised about weird directory structure being generated under the outDir)

@sheetalkamat
Copy link
Member

We already error if tsbuildinfo will be overwritten on tsbuildinfo from referenced projects but the main problem is not all projects might be referenced so its hard to find it out and will depend on how and what you configure. So changing behavior seems unlikely without breaking world.
Also in most setups the tsbuildinfo goes into outDir or next to tsconfig if outDir is not specified unless you configure the options to deteremine your source tree like rootDir. So at that point this custom information does affect where tsbuildinfo will be.
As you suggested, we can give better insight as part of documentation here but i am afraid there isnt much from changing location perspective we can do.

cc: @orta who documents these things and very good at writing these kind of helpers.

@michkot
Copy link
Author

michkot commented Sep 20, 2021

@sheetalkamat / @orta The docs still say "by default, they are in the same folder as your emitted JavaScript." which is simply not true as we saw in this issue-thread. Any chance getting that fixed?
https://www.typescriptlang.org/tsconfig#tsBuildInfoFile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

5 participants