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

Support for multiple tsconfig.json per project #3645

Closed
lazdmx opened this issue Jun 26, 2015 · 37 comments
Closed

Support for multiple tsconfig.json per project #3645

lazdmx opened this issue Jun 26, 2015 · 37 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@lazdmx
Copy link

lazdmx commented Jun 26, 2015

Hi! Is it possible to use multiple tsconfig.json per project, that is some kind of project-wide tsconfig.json located in root directory and additional tsconfig.json files located in sub-directories which may override/tune some options for that dirs? Like .gitignore does.

It would be very usefull when, for instance, developing external module under node-environment. Such modules usually splited into multiple files (internal modules), but would be compiled into one big file during compilation stage.

@DanielRosenwasser
Copy link
Member

Hey @lazutkin. Currently that's not supported, though I just want to link this issue to #2869 because it is somewhat related.

@mhegazy
Copy link
Contributor

mhegazy commented Jun 26, 2015

The compiler picks the closest tsconfig.json to the folder you are building if you are running tsc with no arguments in a folder. so if you have an inner directory with a tsconfig.json it will be picked up before the one in the outer directory.

I do not think we will support integration/overriding configuration from multiple tsconfig.json.

@mhegazy mhegazy added the Question An issue which isn't directly actionable in code label Jun 26, 2015
@Eisenspalter
Copy link

Multiple tsconfig files are indispensable for large enterprise apps.
Suggestion: Everytime tsc find a new tsconfig file in a subdirectory, tsc stopps here and create a new tsc process with its own tsconfig file.

@mhegazy
Copy link
Contributor

mhegazy commented Jul 1, 2015

@Eisenspalter this sounds like a build driver job something like grunt, gulp or msbuild.

@mhegazy mhegazy closed this as completed Jul 1, 2015
@lazdmx
Copy link
Author

lazdmx commented Jul 1, 2015

@mhegazy I agree with @Eisenspalter because we both talk not about building process but about development process including sources writing, testing and other activities we need to complete before build. On all this intermediate steps we need to have support from typescript including intellisense, typechecking etc. Moreover as I said before, for different parts of project we would like to apply different source organizing techniques (external-internal modules, single output file, etc) and here we need some options to be overriden by separate tsconfig.

@Eisenspalter
Copy link

@mhegazy Why closed? Please reopen.

@mhegazy
Copy link
Contributor

mhegazy commented Jul 1, 2015

you can have multiple tsconfig today, each pointing to overlapping set of files. so one at src\tsconfig.json, one in tests\tsconfig.json, etc.. the compiler/tools will locate the file by walking up the directory tree to find the closest one. so you can have a third file at the root to catch all.

This all works today, in the compiler and the different IDEs. the original issue was about allowing a file to inherit from another. i do not think there is enough value there warrants the complexity.

For the second issue:

Everytime tsc find a new tsconfig file in a subdirectory, tsc stopps here and create a new tsc process with its own tsconfig file.

As i mentioned earlier, a tsconfig.json represents a single invocation to tsc.js/tsc.exe if you want to do multiple invocations you should use a build driver.

@lazutkin and @Eisenspalter does this answer the questions

@Ziink
Copy link

Ziink commented Dec 12, 2015

@mhegazy
Couldn't get multiple tsconfig.json to work. At least with TypeScript 1.7.3, only one tsconfig.json is read and that is expected to be in the root directory (or parent) of the project.

@mhegazy
Copy link
Contributor

mhegazy commented Jan 5, 2016

@Ziink my comment above was not about multiple tsconfigs in the same project. it was about multiple projects/directories, each with a different tsconfig. this how the ts project is layed out, see https://github.com/Microsoft/TypeScript/tree/master/src, each folder under src, has a different tsconfig.json

@bartosz-k
Copy link

I have project that is written in TypeScript and I want to target both:

  1. browser (let's say files in /browser) with ES5/AMD and
  2. nodejs (files in server) with CommonJS and generators (and async/await in TS).

There are some shared files let's say in (/common) folder and there are imports from common to browser and server.
How can I achieve such config preserving IDE support, all the errors etc? I'm not sure if the discussion answered my doubts.

@mhegazy
Copy link
Contributor

mhegazy commented Feb 23, 2016

@Bartq With TS 1.8, I would create two tsconfig files, one for browser, and one for server, and add ///references in your files in both sub-projects to the common ones. give it a try and let us know if this addresses the scenario or there are still missing pieces.

@bartosz-k
Copy link

actually I'm using those two tsconfig.json files, WebStorm discovers them and runs the compilation automatically. To be precise, backend code imports some classess from frontend code (instead using common concept), but it all works fine.

@mignonat
Copy link

mignonat commented Apr 9, 2016

I finally get the solution.

my application structure :
-- app/
-- app/client/ (my client side source code)
-- app/server/ (my server side source code)
-- app/build/ (where I generate the js)
-- app/node-modules/
-- app/package.json
-- app/tsconfig.server.json
-- app/tsconfig.client.json

Content of tsconfig.server.json :
{ "compilerOptions": { ..., "outDir": "build/server" },
"exclude": [ "node_modules", "client"] }

Content of tsconfig.client.json :
{ "compilerOptions": { ..., "outDir": "build/client"},
"exclude": [ "node_modules", "server"] }


Then when I want to compile server source code I use this command from app root directory :
#tsc --p tsconfig.server.json


And to compile client source code, also from root app directory :
#tsc --p tsconfig.client.json


In order to run both client & server compilation, I added a command in package.json :

"scripts": { ..., "tsc": "tsc --p tsconfig.server.json && tsc --p tsconfig.client.json", ... }

Then to compile both server and client I just run this from my root app directory :
#npm run tsc

Hope this comment could help you :-)

@Roaders
Copy link

Roaders commented May 9, 2016

I don't understand what the problem is here. Why can't we support configs with different file names? It's a pain having to create subFolders JUST to have a different tsconfig file in.

@mhegazy
Copy link
Contributor

mhegazy commented May 9, 2016

You can. --p argument ca be a file name.

@crush83
Copy link

crush83 commented May 26, 2016

The different file names won't work with the Visual Studio typescript compiler extension (not talking about CLI) out of the box though. Only way to do that is to put each tsconfig.json in a dummy directory, and have it link back to the typescripts you want with the files option.

for example

--src/target/search/tsconfig.json
--src/target/core/tsconfig.json
--src/target/users/tsconfig.json

target/search/tsconfig.json would look something like:

{
  "compilerOptions": {
    "outFile": "../../../build/app/search.js"
  },
  "files": [
    "../../src/common",
    "../../src/search"
  ]
}

And the others would be similar.

This would produce 3 javascript files, each with its own configuration of files, bundled into one.

Of course, your could use a different solution of bundling/minimizing/packaging than the Typescript compiler itself.

It's just that the Typescript compiler does a really good job with optimization - that's one of the biggest draws to using Typescript.

So, it would be nice if a single tsconfig.json could support multiple configurations by just changing it to be an array of tsconfigs:

[
  {
    "compilerOptions": {
      "outFile": "../../build/search.js"
    },
    "files": [
      "src/common",
      "src/search"
    ],
    "compileOnSave": true
  },
  {
    "compilerOptions": {
      "outFile": "../../build/core.js"
    }
    "files": [
      "src/common",
      "src/core"
    ],
    "compileOnSave": true
  }
]

This is what it sounds like is being requested in the later comments of this issue, although I agree, the original issue was more about inheritance and overriding configs.

@tomitrescak
Copy link

@mhegazy @Bartq I cannot make it work with tsc command.
I have a following directory structure

-- app/
-- app/server  -- here I want es6/commonjs
-- app/server/tsconfig.json
-- app/client    -- here I want es6/es6 
-- app/client/tsconfig.json
-- app/tsconfig.json

Yet, when I run tsc only config from app/tsconfig.json is used, rest is ignored. I'm trying to make it work in VSCode :/

@bartosz-k
Copy link

@tomitrescak I'm using WebStorm and it's intelligent enough to find closest tsconfig.json and use it when you edit a file. Probably there isn't any cmd tool that supports watching multiple tsconfig.json's. You can roll it out using for example FB watchman.

@tomitrescak
Copy link

Yeah, I'd love to have something like this in VS Code. I'm running the compilation in the terminal. Works as well. VS Code correctly identifies errors anyways.

@yvbeek
Copy link

yvbeek commented Sep 23, 2016

Multiple configs would be great. I am working on a React-Native project and basically I have two builds that I want to do:

  1. the scripts of my React-Native project
  2. the scripts used in the HTML for the React-Native WebViews (charts).

@mhegazy
Copy link
Contributor

mhegazy commented Sep 23, 2016

Configuration inheritance has been added in TS 2.1, and should be available in typescript@next today. see #9876 for more details. With that you can have a "master" tsconfig.json and override ones that inherit configurations from it. you still need to create multiple tsconfig.json files, but your IDE should pick these up.

@KostyaTretyak
Copy link

KostyaTretyak commented Jan 29, 2017

I have a following directory structure:

├── examples
│   ├── files...
│   └── tsconfig.json
├── src
│   └──files...
└── tsconfig.json

Root tsconfig.json have:

{
  "compilerOptions": {
    "target": "es2015",
    "module": "commonjs",
    "moduleResolution": "node",
    "outDir": "dist",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "declaration": true,
    "allowJs": false
  },
  "include": [
    "./src"
  ],
  "compileOnSave": false,
  "buildOnSave": false,
  "atom": { "rewriteTsconfig": false }
}

examples/tsconfig.json have same value except:

  "include": [
    "./hello-world"
  ],

When I do:

cd examples
tsc

It compiles:

├── examples
│   ├── dist
│   │   ├── examples
│   │   └── src
│   ├── files...
│   └── tsconfig.json
├── src
│   └──  files...
└── tsconfig.json

(dist wrong incluedes external folder src and compiles as from within the root folder)

Not help this (in examples/tsconfig.json):

  "exclude": [
    "../src"
  ],

What am I doing wrong?

@KostyaTretyak
Copy link

KostyaTretyak commented Jan 30, 2017

I found problem. If in my examples/hello-world/any-file*.ts this import:

import { SomeClass } from '../../src';

It's produce described above problem. Following import works as expected:

import { SomeClass } from '../../';

But why typescript's directive include not works as expected?

@zhukovka
Copy link

I can't get it working
It insists on "Warning:Cannot find parent tsconfig.json" although I have tsconfig.json in the same folder, don't know what to do with this

@RyanCavanaugh
Copy link
Member

@zhukovka please log a new issue with a standalone repro we can run locally

@zhukovka
Copy link

@RyanCavanaugh Oh. thanks, I've figured it out
the problem reproduces only if I have one file open from a test folder (that didn't include tsconfig.json) and the second file opened in an 'src' folder (that included tsconfig.json)
and the file from the test folder imports the one from the src folder. In this case, the file from the src folder doesn't see his 'parent tsconfig.json'

@BurtHarris
Copy link

@RyanCavanaugh, support for compiling with several different tsconfig.json's seems to continue be something developers would like to have. For my cases, its generally about changing where the generated output files go. It seems like if the code generations could be controlled by something like the existing paths mapping allowing me to layout my generated code differently from the sources, perhaps the need for multiple projects would be lessened.

@pelotom
Copy link

pelotom commented Aug 29, 2017

My use case is that I have a large legacy codebase which can't withstand the stricter type checking rules, and I want to use it in a new codebase which does have strict checks enabled, and I can't compile the legacy code to a library because it has a million cases where it doesn't import all the types required to name the types for its exports (#9944). So I want to just add the legacy codebase to the new codebase, but compiled according to laxer rules. This can't be 2 different compilation steps; just when the compiler is working on source files under a certain directory it should be using the laxer rules.

@voy
Copy link

voy commented Sep 7, 2017

For me the use case is having part of the repo that is run using node and needs to compile down to commonjs modules, while the other part needs to be compiled to ES6 modules in order to enable treeshaking in ES6. The experience isn't great, there is a lot of hacking around with TS_NODE_PROJECT environment variables, in my case. It definitely seems like something that could confuse the hell out of the next person maintaining it when I eventually change projects.

@Robinfr
Copy link

Robinfr commented Sep 15, 2017

I would still love to see this solved. It would be a huge win for larger projects that require different tsconfig.json files per module within a project.

@kitsonk
Copy link
Contributor

kitsonk commented Sep 15, 2017

@Robinfr what does the extends feature not solve for you?

@Robinfr
Copy link

Robinfr commented Sep 15, 2017 via email

@voy
Copy link

voy commented Sep 19, 2017

@kitsonk extending works well, although if I am not doing something wrong, I have to repeat certain settings (excluding my build and node_modules folders) in both configs. for me the biggest pain point is making sure all my tooling knows which configuration file is the correct one too use (typically by means of something like a TS_NODE_PROJECT environment variable. The other is when opening a project with two tsconfigs in VS.code. There is no way (that I know of) to tell VS which project file to use and that means for some files errors will not get correctly underlined, because of different settings for those files in the corresponding tsconfig (say, something like tsconfig.build.json).

@Robinfr
Copy link

Robinfr commented Sep 20, 2017

@voy may I ask why you have a different tsconfig for building? As far as I've understood, VSCode uses the nearest tsconfig file (tsconfig.json) to the file you're editing. The only issue I've had so far is that you need to have a tsconfig file at the root before VSCode seems to start using the configs at all...

@voy
Copy link

voy commented Sep 20, 2017

@Robinfr sure. in the same repository I have files that get processed using webpack & babel and use ES6 modules to enable tree-shaking. other files are part of the build process and get executed using node, which is why imports need to get transpiled to requires. not sure how I could work around that.

@Robinfr
Copy link

Robinfr commented Sep 20, 2017

@voy wouldn't you just have those files in a separate folder however? E.g. 1 folder for all the Babel & webpack files, and 1 for the node files. Then you can just have a tsconfig.json for each of those folders. Wouldn't that work for you?

@voy
Copy link

voy commented Sep 21, 2017

@Robinfr that would be ideal, but I think it isn't always possible in the real world. for example, we want all our configuration files to be typescript as well, compiled and linted according to the very same rules as all of TypeScript codebase and some files have to be in the root of the project. you could symlink, but that sometimes brings out other problems. that's why I feel something more flexible would be a benefit.

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests