TypeScript: The `compilerOptions.outDir` config is incorrectly resolved when in a shareable config
TypeScript Version: 3.3.0-dev.20181222
Search Terms: outDir
, output directory
, outDir extends
Expected behavior:
TypeScript 3.2 got support for configuration inheritance via node_modules packages. I have created a package with a shareable config. In this shareable config, I have defined the outDir
option: https://github.com/sindresorhus/tsconfig/blob/50b0ba611480ed45b97a59b910f5bb5e8cbc25ef/tsconfig.json#L2-L3 as I always use the same outDir
and don’t want to have to specify it in each project.
I expected the outDir
path to be resolved against the project root, even when it’s defined in an extended config.
Actual behavior:
It turns out the outDir
relative path is actually resolved against the shareable config path instead of the project’s root (tsconfig.json
) path. So when I have a project foo
, and compile TypeScript, the output ends up in foo/@sindresorhus/tsconfig/dist
instead of foo/dist
.
You can reproduce it by cloning https://github.com/sindresorhus/ow/tree/8ae048c4931dfd51b496cefb40b24c78d3722be6, then removing this line https://github.com/sindresorhus/ow/blob/8ae048c4931dfd51b496cefb40b24c78d3722be6/tsconfig.json#L4 (which is a workaround to the problem), and then run $ npm test
. The compiled TS code will end up in node_modules/@sindresorhus/tsconfig/dist
instead of dist
.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 82
- Comments: 30 (4 by maintainers)
Commits related to this issue
- Remove path related options https://github.com/Microsoft/TypeScript/issues/29172 — committed to realplatanopapi/tsconfig by realplatanopapi 5 years ago
- chore: remove path properties BREAKING CHANGE: Removed the following properties: - `compilerOptions.rootDir` - `compilerOptions.outDir` - `include` The reason for this removal is the following issue:... — committed to mightyiam/tsconfigs by mightyiam 5 years ago
- Solve a problem with tsconfig https://github.com/microsoft/TypeScript/issues/29172 — committed to iVis-at-Bilkent/pathway-mapper by msalihaltun 3 years ago
- feat: add initial tsconfig bases - base, library, and library-build, same as the package exports - initially started with library, but if I wanted to use this repo for apps as well, I wouldn't ... — committed to agilgur5/tsconfig by agilgur5 2 years ago
- Removed path-based config options Reference: https://github.com/microsoft/TypeScript/issues/29172#issuecomment-450966221 — committed to finsweet/tsconfig by alexiglesias93 2 years ago
- deps: use @agilgur5/tsconfig to simplify tsconfig Basically same as https://github.com/agilgur5/react-signature-canvas/commit/cc6cce9f7920a33096e36186eb7d4ae5b8f50a46 - this is my own tsconfig base ... — committed to agilgur5/ts-library-base by agilgur5 2 years ago
- fix: fix tsconfig Paths in tsconfig are relative to the config fine in which they are declared. So any path declared in `packages/tsconfig/base.json` is relative to that directory. This applies in pa... — committed to dzangolab/vue by opichon 2 years ago
- dirs are relative to the source project. until https://github.com/microsoft/TypeScript/issues/29172 makes its way into a release at least — committed to Gnuxie/tsconfig by Gnuxie 2 months ago
Rather than a breaking fix, couldn’t one just handle placeholder variables, such as $PROJECT_DIR or $ROOT_DIR? So the
outDir
in my common config file could be"$PROJECT_DIR/lib"
?Path-based compiler options (
outDir
,outFile
,rootDir
,include
,files
) are resolved from the config file they’re found in - we thought this’d be more consistent when combining config files, especially when you have multiple configs within the same project, as paths always get resolved relative to the file they were written in (so you can safely write references to any path you want in a config file without worrying about if that config getsextend
’d later on - its paths will continue to work).It would be horribly breaking to change this behavior now~
As per @MartinDoyleUK 's suggestion - which is similar to what Jest has done with
<rootDir>
, please add a$ROOT_DIR
option to support this common use case.Just want to chime in, I’m really surprised these paths are resolving relatively. This really makes config extensions much less useful.
I really just want to set my
rootDir
andoutDir
across all of my packages uniformly by extending a singular base configuration - there’s no way to do that right now without definingrootDir
andoutDir
in every single one of my packages.Took me a hot minute to find my build files inside
node_modules/@myorg/shared-tsconfigs/dist
… 😭But this makes “extends” pretty useless. Without outDir you cannot use project references with extends. A The use case for extends is that I specify baseline options for the compiler but paths and references should be based on project settings. It should be possible overwrite paths or even individual options.
@myscope/tsc-config/tsconfig.base.json
@myscope/my-project/tsconfig.json
Resolved config:
This should be a non-breaking change.
4 years and we still can’t get one of the non-breaking solutions merged?
@weswigham any news on this?
I found @MartinDoyleUK’s idea to intro
$PROJECT_DIR
or$ROOT_DIR
vars quite smart and they aren’t a breaking change.I think this is very confusing, I read the docs about extends and when I read:
I took this at it’s word that if I used a relative path such as
in the base configuration path would be resolved relative to the base configuration’s path. The implication here is that non-relative paths are not relative to where they appear but rather the project wherever
tsc
is run, so I expect:to be relevant to the project.
It seems however that
src
and./src
are both identical wrt extends which seems like a very unintuitive decision.This is honestly crazy. about five years later and we still don’t have anything.
even just an extra config property we could put in the base/shared config like
outDirBaseUrlOverride
orallowExtendOutDir
would be a good simple fix which i cant imagine being a breaking change as its something that needs to be manually enabledWe’re discussing options about this at #56436
I ran into this while making pnpm use a shared config.
It’s such a surprise that
extends
resolves path relatively to the source config rather than the inhering config.Consistency? YES definitely. Use case? NO Don’t think so.
As a workaround, here is my hack:
tsconfig.json
to the same directory of target project e.g.tsconfig.json
which extendstsconfig.base.json
e.g.Would be great if suggestion such as #30163 can be accepted!!!
Hello from 2024, this is still an issue.
Wow, great to know a solution has been implemented and merged!
https://github.com/microsoft/TypeScript/pull/58042
As far as I understand it, soon we should be able to write a base config such as:
Is typescript still maintained?
I just was making a new project in TS (pretty much the first time I’m doing a monorepo TS project from the scratch) and I also faced this issue. I was expecting paths to be resolved from the “final”
tsconfig.json
file.None of workarounds menitoned during the discussion works. I also have a feeling that adding root directory variable would be a viable solution to this - though discovery of it wouldn’t be perfect.
The only solution for me is to use:
Which is not ideal but still makes few lines to be reused.