GeezerVison is showing github.com — Support for tsconfig.json files by ahejlsberg · Pull Request #1692 · microsoft/TypeScript
Conversation
This PR implements #1667 with some modifications.
The presence of a tsconfig.json file in a directory indicates that the directory is the root of a TypeScript project. The tsconfig.json file specifies the root files and the compiler options required to compile the project. A project is compiled in one of the following ways:
- By invoking tsc with no input files, in which case the compiler searches for the tsconfig.json file starting in the current directory and continuing up the parent directory chain.
- By invoking tsc with no input files and a
-project (or just -p) command line option that specifies the path of a directory containing a tsconfig.json file.
When input files are specified on the command line, tsconfig.json files are ignored.
An example tsconfig.json file:
{
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"out": "../../built/local/tsc.js",
"sourceMap": true,
},
"files": [
"core.ts",
"sys.ts",
"types.ts",
"scanner.ts",
"parser.ts",
"utilities.ts",
"binder.ts",
"checker.ts",
"emitter.ts",
"program.ts",
"commandLineParser.ts",
"tsc.ts",
"diagnosticInformationMap.generated.ts"
]
}
The "compilerOptions" property can be omitted, in which case the compiler's defaults are used.
If no "files" property is present in a tsconfig.json, the compiler defaults to including all files the containing directory and subdirectories. When a "files" property is specified, only those files are included.
A tsconfig.json file is permitted to be completely empty, which compiles all files in the containing directory and subdirectories with the default compiler options.
Compiler options specified on the command line override those specified in the tsconfig.json file.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
This allows watch as a compiler option in the file. Should it be ignored?
When input files are specified on the command line, tsconfig.json files are ignored.
Why is the entire file ignored instead of just the files section? It would be useful to partially compile a project by specifying individual files, but using the compiler options specified in the project file.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Arnav Singh (@Arnavion) I agree, we should probably disallow watch in tsconfig.json. Same for project which only makes sense on the command line.
Regarding your second question, I'd like to do what you suggest, but I wonder about this scenario: Say you have directories c:\src\foo and c:\src\bar, each containing a tsconfig.json, and that the current directory is c:\src\foo. Now if you say tsc c:\src\bar\somefile.ts we'd compile a file from the c:\src\bar project with the options of the c:\src\foo project. This may be just fine, but perhaps also confusing.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
That makes sense. You could expect it to use the tsconfig.json based on the file being compiled (c:\src\bar\tsconfig.json), but then that won't work if you wanted to compile files from both directories with the same commandline. Compiling with the tsconfig.json based on the current directory would be deterministic but, as you said, not intuitive either.
One alternative is:
- For each file, find the tsconfig.json relative to it (the same directory-tree-climbing algorithm as now).
- If all files map to a single project file, use it.
- Else print an error ("Multiple project files found. Please specify one with -p") and abort.
It'll probably be more common for all the individual files being compiled to be in the same project, so this approach would allow them to be compiled with that project file. On the other hand it's more complicated, and expensive if the files are in multiple directories.
Then again, this might not even be really necessary. The use case I was imagining was that someone makes a change to only a few files of a large project and wants to recompile those files, but perhaps they'd be okay with just compiling the whole project every time. Or they could use automation like tsc -watch, watchify, etc. to only compile the changed files.
I guess the current behavior is fine.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Anders Hejlsberg (@ahejlsberg)
When a "files" property is specified, only those files are included.
I am thinking why would anyone want to have .ts files in a directory and not have them compiled?
Perhaps an "exclude": [ "foo/bar.ts" ] would make more sense?
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
+1 for the exclude behavior.
One question: can I combine regular command line options with the -p option E.g. tsc -p src -module "commonjs"
If you share code between the browser and nodejs and you need to compile the code once for commonjs and once for amd it would make sense to only maintain one tsconfig.json file.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Noel Abrahams (@NoelAbrahams) I think there are two important scenarios: (1) Let me drop an empty tsconfig.json file in a directory and have everything in there be a project, and (2) let me describe the exact list of files I want included. The current design covers both with a minimum of complexity. That said, I can certainly see how an "exclude" list could be useful, although I suspect we'd then need globbing as well, so the level of complexity goes up. I definitely don't want this growing into an alternate build system. The intent is more to offer tools (e.g. editors) a simple and deterministic way to decide what the compilation context for a particular file is.
Dirk Bäumer (@dbaeumer) Yes, you can combine other command line options with -p.
|
TomasHubelbauer reacted with thumbs down emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
I think there are two important scenarios: (1) Let me drop an empty tsconfig.json file in a directory and have everything in there be a project, and (2) let me describe the exact list of files I want included. The current design covers both with a minimum of complexity. That said, I can certainly see how an "exclude" list could be useful, although I suspect we'd then need globbing as well, so the level of complexity goes up. I definitely don't want this growing into an alternate build system. The intent is more to offer tools (e.g. editors) a simple and deterministic way to decide what the compilation context for a particular file is.
Honestly if your target is editor I would prefer that this feature never make it to master. If those configuration files are implemented, I will have to support them, if I want to offer more complex configuration mechanisms, I will have to support another config file and figure when a file configuration has precedence over another.
Build/project configuration has always be a topic where everyone make its own sauce, the amazing number of build/lint/configuration tools is a good example of that.
I don't clearly see the value of those tsconfig.json file over storing the command line in simple bash script, however I'm pretty much sure they will give me headache when I'll have to decide how I should integrate them.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
I agree with François de Campredon (@fdecampredon) that this PR might not be a good idea for IDE developers. Nevertheless
Perhaps an "exclude": [ "foo/bar.ts" ] would make more sense?
No. Better to have !foo/bar.ts included in files than to add another option to the root. If this PR does get merged I would as a second step recommend making files support the entire glob/minmatch/regexp syntax common in JavaScript build tools. Having a custom hacked exclude option would just be painful to allow that next step. You would pretty soon want to do exclude: node_modules/**/*.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Basarat Ali Syed (@basarat) Anders mentioned that already:
That said, I can certainly see how an "exclude" list could be useful, although I suspect we'd then need globbing as well, so the level of complexity goes up.
The problem with supporting globbing is that it needs to be an own-implementation, since tsc can't rely on node modules. This is why the previous PR for wildcards was abandoned.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
What's wrong with exclude: [ node_modules/**/*]? That's what people do already with .gitignore. I'm not suggesting that exclude be another option, rather it should be the only option. There's no real need for files. A directory already adequately describes that.
As I see it:
- Use the file system to describe the project structure
- Use
.gitignore (or equivalent) to share that structure amongst your team
- Use
tsconfig.json to build the project structure
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Noel Abrahams (@NoelAbrahams) There are actually two very real needs for files:
- It allows you to specify a file ordering, which matters in projects that use
-out.
- It allows you to reference files outside this directory tree. This is particularly important for referencing declarations files.
Yes, you can cover those with /// <reference /> but a lot of folks don't like putting those in their programs.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Anders Hejlsberg (@ahejlsberg), Ah! I failed to spot the potential for including references.
The only objection I have is to the following:
When a "files" property is specified, only those files are included.
In the project structure we have, all files are included in the compilation, including subdirectories.
But certainly, I would like to see ordering and referencing to be part of this.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Anders Hejlsberg (@ahejlsberg), this fails hard if you have a loop in your file system and "files" isn't specified.
compiler Daniel$ ln -s uhoh .
compiler Daniel$ node ../../built/local/tsc.js
fs.js:689
return binding.stat(pathModule._makeLong(path));
^
Error: ELOOP, too many symbolic links encountered 'uhoh'
at Object.fs.statSync (fs.js:689:18)
at visitDirectory (/Users/Daniel/TypeScript/built/local/tsc.js:1334:40)
at Object.readDirectory (/Users/Daniel/TypeScript/built/local/tsc.js:1327:17)
at getFiles (/Users/Daniel/TypeScript/built/local/tsc.js:20219:39)
at Object.parseConfigFile (/Users/Daniel/TypeScript/built/local/tsc.js:20167:24)
at Object.executeCommandLine (/Users/Daniel/TypeScript/built/local/tsc.js:20389:40)
=== Snip ===
This is mostly a problem if we let others consume this functionality.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Just to clarify my point above. We would like to make use of the external file reference and ordering feature introduced by files, but then we're also forced to include the files that need to be compiled, because one cannot have one without the other as it stands.
This introduces a maintenance problem: every time a new file is added or an existing file deleted tsconfig.json needs to be modified; and there is danger of files being inadvertently excluded from compilation.
If this change is accompanied by associated changes to the tooling (i.e. in Visual Studio for instance the "Add file" feature should automatically update tsconfig.json) then that should be fine.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Noel Abrahams (@NoelAbrahams) perhaps solvable by a third party tool :
support a files-expansion:['!somefile','must/include/**/*.ts'] sort of transform inside tsconfig.json which will expand the files member.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Basarat Ali Syed (@basarat), that is an option.
But I would prefer the syntax be simple. We expect to have 40+ tsconfig.json files and things may get out of hand.
Perhaps "files": [*] as a shortcut to include all files in the current directory and all subdirectories.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Perhaps "files": [*] as a shortcut to include all files in the current directory and all subdirectories.
Noel Abrahams (@NoelAbrahams) isn't this already take care of by (see original PR comments):
If no "files" property is present in a tsconfig.json, the compiler defaults to including all files the containing directory and subdirectories.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Basarat Ali Syed (@basarat) we would interested to hear how grunt-TS would be using this and if there are any changes on the compiler side you would need
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Any information yet in which release this will be available? (incl. VS-support?)
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
This will be in the 1.5 release. Not sure yet what level of VS support we'll have in that release.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Feb 4, 2015
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Basarat Ali Syed (@basarat) Awesome. Thanks. Are you sure all those options are supported in tsconfig.json files too? Where's the official documentation for these options so I can get the proper description text?
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Thanks, I've removed the experimental options
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Is
files:['./someDirectory/'] ( == files:['someDirectory/'] )
equivalent to
files:['./someDirectory/**/*.ts']
?
If not so, could you add support for this? I wouldn't like compiler to waste time looking into /bower_components/ or /node_modules/ folders, meaning that I'd like to "easily" specify the folders to include in the project...
(* Function Definition *)
function Salute(): string;
var
(* mmm... none... *)
begin
writeln( 'Thank you :)');
end;
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
equivalent to
No. It must point to a file. No gobbing support yet.
Requested here : #1927
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Is there a reason that the --rootDir tsc command option is not included in the tsconfig.json schema? I'm using 1.5.0-beta.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
I think it's a bit silly to disallow globs because a small percentage of use-cases would not work, when the majority of use-cases need it.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
The use for filesGlob is so great - to do exclusions of the node_modules and other dirs, which cause tsc to choike. VSCode is crippled without this.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
sigh I wish that:
a) The web community would unify on adopting a .config directory in the root of a project to store this eve-expanding list of config files.
b) Config file definitions could be unified into a standard format. Why can't it just be config.json, with a definition specific for TypeScript, like package.json? And then Sass, Less, and others could all define their respective config.json settings (or alternatively, .config/config.json), that an IDE could import?
I think it's really unfortunate this idea was implemented in this way. 😢
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Isn't that what the.{file} notation is for. Files that are hidden and special.What's wrong with having .gitignore, .vscode, .tsconfig. they all target different purposes.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|