I have the following directory structure:
.
├── tsconfig.json ("module": "CommonJS")
└── foo/
├── node-file.ts
└── bar/
├── browser-file.ts
└── tsconfig.json ("module": "esnext")
The root tsconfig.json
has module
set to CommonJS
because I want most of my files to compile for Node. But inside bar
, I want the files to compile to JavaScript Modules, so I've set module
to esnext
.
Now when I run tsc
from the root, I expect node-file.ts
to compile to CommonJS
module and browser-file.ts
to compile to a JavaScript Module. But that's not what I'm getting. It seems that tsc
is completely ignoring foo/bar/tsconfig.json
and is only picking up the root tsconfig.json
.
(I also use tsc --watch
while developing, so I'm trying to avoid having to run two different tsc
processes to compile the two different targets. It feels to me that running a single tsc
with nested tsconfig.json
files should give me the desired results.)
Anyone know what it is that I'm doing wrong?
You could use multiple tsconfig files to solve some of those problems, but new ones would appear: There's no built-in up-to-date checking, so you end up always running tsc twice.
The tsconfig.json file specifies the root files and the compiler options required to compile the project. JavaScript projects can use a jsconfig.json file instead, which acts almost the same but has some JavaScript-related compiler flags enabled by default.
TypeScript only uses one tsconfig.json
and doesn't automatically use subdirectories' tsconfig.json
for the files there. However, you can use project references for this.
Create a directory structure like this:
.
├── tsconfig.json
├── tsconfig.settings.json (optional)
└── foo/
├── node-file.ts
├── tsconfig.json ("module": "commonjs")
└── bar/
├── browser-file.ts
└── tsconfig.json ("module": "esnext")
tsconfig.json
{
"files": [],
"references": [
{"path": "./foo"},
{"path": "./foo/bar"}
]
}
This is the root tsconfig.json
. When you run tsc --build
(see below) in the root directory, TypeScript will build the referenced projects ./foo/tsconfig.json
and ./foo/bar/tsconfig.json
.
The "files": []
is to stop accidental tsc
s without --build
from attempting to compile everything in the root directory, which will error but create multiple .js
files in possibly the incorrect places.
tsconfig.settings.json
(optional)
{
"compilerOptions": {
"strict": true,
"noImplicitReturns": true
}
}
You can put configuration common to foo
and foo/bar
and extend this configuration with extends
to reduce duplication. Note that all relative paths in here will be resolved relative to tsconfig.settings.json
when extended, so something like "outDir": "dist"
may not work as expected.
foo/tsconfig.json
{
"extends": "../tsconfig.settings.json",
"exclude": ["bar/**/*.ts"],
"compilerOptions": {
"module": "commonjs"
}
}
This is the configuration for the CommonJS files. It also extends the common config and excludes the files in foo/bar
.
foo/bar/tsconfig.json
{
"extends": "../../tsconfig.settings.json",
"compilerOptions": {
"module": "esnext"
}
}
This is pretty similar to foo
's configuration.
To compile foo
and foo/bar
at the same time, use build mode from the root directory:
tsc --build # or tsc -b
# Watch mode:
tsc --build --watch # or tsc -b -w
From the handbook:
A long-awaited feature is smart incremental builds for TypeScript projects. In 3.0 you can use the
--build
flag withtsc
. This is effectively a new entry point fortsc
that behaves more like a build orchestrator than a simple compiler.Running
tsc --build
(tsc -b
for short) will do the following:
- Find all referenced projects
- Detect if they are up-to-date
- Build out-of-date projects in the correct order
You can provide
tsc -b
with multiple config file paths (e.g.tsc -b src test
). Just liketsc -p
, specifying the config file name itself is unnecessary if it’s namedtsconfig.json
.
You can also compile individual projects:
tsc -b foo # or cd foo && tsc
tsc -b foo/bar # or cd foo/bar && tsc
Note that are some build-only flags and you cannot override compiler options with command-line arguments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With