これは、なにをしたくて書いたもの?
tsconfig.jsonにどういうものを指定したらいいんだろう?という気になるのですが、なにか参考になるものが欲しいところです。
このような目的でTSConfig Basesというものがあるらしいので、少し見てみました。
TSConfig Bases
TSConfig BasesはTypteScriptのドキュメントで紹介されています。
Depending on the JavaScript runtime environment which you intend to run your code in, there may be a base configuration which you can use at github.com/tsconfig/bases. These are tsconfig.json files which your project extends from which simplifies your tsconfig.json by handling the runtime support.
What is a tsconfig.json / TSConfig Bases
リファレンスの方には載っていないのですが…。
TSConfig Basesは特定のランタイム環境に合わせて調整された、tsconfig.jsonをホストしたものです。
GitHubリポジトリーはこちら。
使い方はドキュメントに書かれているように、パッケージマネージャーでインストールして
$ npm install --save-dev @tsconfig/recommended $ yarn add --dev @tsconfig/recommended
tsconfig.jsonでextendsします。
"extends": "@tsconfig/recommended/tsconfig.json"
これはRecommendedを使った例です。
現時点で、これだけの種類があります。
| 名前 | npmパッケージ名 |
|---|---|
| Recommended | @tsconfig/recommended |
| Bun | @tsconfig/bun |
| Create React App | @tsconfig/create-react-app |
| Cypress | @tsconfig/cypress |
| Deno | @tsconfig/deno |
| Docusaurus v2 | @tsconfig/docusaurus |
| Ember | @tsconfig/ember |
| Next.js | @tsconfig/next |
| Node LTS | @tsconfig/node-lts |
| Node 10 | @tsconfig/node10 |
| Node 12 | @tsconfig/node12 |
| Node 14 | @tsconfig/node14 |
| Node 16 | @tsconfig/node16 |
| Node 17 | @tsconfig/node17 |
| Node 18 | @tsconfig/node18 |
| Node 19 | @tsconfig/node19 |
| Node 20 | @tsconfig/node20 |
| Node 21 | @tsconfig/node21 |
| Node 22 | @tsconfig/node22 |
| Nuxt | @tsconfig/nuxt |
| React Native | @tsconfig/react-native |
| Remix | @tsconfig/remix |
| Strictest | @tsconfig/strictest |
| Svelte | @tsconfig/svelte |
| Taro | @tsconfig/taro |
| Vite React | @tsconfig/vite-react |
RecommendedとStrictestはちょっと気になるところ。あとは使う環境に応じて、各ランタイムやフレームワーク向けのものを見ていく
感じでしょうか。
どのような設定になっているかは、README.mdのリンクから各パッケージのnpm上でのドキュメントを見るか、
直接ソースコードを見てもよいでしょう。
https://github.com/tsconfig/bases/blob/ebe629c2857d386a0bc2c5d60cab18b9f1a425d0/bases/strictest.json
https://github.com/tsconfig/bases/blob/ebe629c2857d386a0bc2c5d60cab18b9f1a425d0/bases/node20.json
リリースタグはないので、コミットハッシュを見るしかなさそうですね。
また、こういうファイルの用意のされかたを見ると、「Recommended+Node.js 20」のような設定がしたいと思ったりするのですが、
組み合わせ方はこちらに書いています。
Centralized Recommendations for TSConfig bases / What about combined configs?
以前はtsconfig.jsonのextendsをひとつしか指定できなかったので、このリポジトリーでも組み合わせの構成を提供していたようです。
TypeScript 5.0以降はextendsが拡張されて複数の指定が可能になったので、利用者側で組み合わせられるようになりました。
以下はREADME.mdに載っているStrictest(最も厳しい)+Node.js 18の例です。
// tsconfig.json { "extends": ["@tsconfig/strictest/tsconfig", "@tsconfig/node18/tsconfig"] }
このテーマだけを独立させて書いたのが、こちらのエントリーだったりします。
TypeScript 5.0からtsconfig.jsonのextends元を複数指定できるようになっていたという話(+showConfigで最終結果確認) - CLOVER🍀
こんな感じでだいたい使い方の雰囲気はわかったのですが、簡単に試しておきましょう。
環境
今回の環境はこちら。
$ node --version v20.16.0 $ npm --version 10.8.1
準備
Node.jsプロジェクトを作成して、TypeScriptをインストール。
$ npm init -y $ npm i -D typescript $ npm i -D @types/node@v20
バージョン。
"devDependencies": { "@types/node": "^20.14.8", "typescript": "^5.5.4" }
あとでextendsを追加するためのtsconfig.jsonも作成しておきます。
tsconfig.json
{ "compilerOptions": { "baseUrl": "./src", "outDir": "dist" }, "include": [ "src/**/*" ] }
トランスパイル用のダミーのソースコードも作成。
$ mkdir src
$ echo "console.log('Hello World');" > src/hello.ts
tscが動作するところまでは確認しておきます。
$ npx tsc
TSConfig Basesをベースにtsconfig.jsonを作成する
それでは、TSConfig Basesを使ってみましょう。
まずはNode.js 20用のtsconfig.jsonをインストールしてみます。
$ npm i -D @tsconfig/node20
依存関係はこうなりました。
"devDependencies": { "@tsconfig/node20": "^20.1.4", "@types/node": "^20.14.8", "typescript": "^5.5.4" }
これをtsconfig.jsonのextendsに追加します。
tsconfig.json
{ "extends": "@tsconfig/node20/tsconfig.json", "compilerOptions": { "baseUrl": "./src", "outDir": "dist" }, "include": [ "src/**/*" ] }
--showConfigフラグで最終結果を表示してみます。
$ npx tsc --showConfig
{
"compilerOptions": {
"lib": [
"es2023"
],
"module": "node16",
"target": "es2022",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"moduleResolution": "node16",
"baseUrl": "./src",
"outDir": "./dist",
"moduleDetection": "force",
"allowSyntheticDefaultImports": true,
"resolvePackageJsonExports": true,
"resolvePackageJsonImports": true,
"useDefineForClassFields": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"alwaysStrict": true,
"useUnknownInCatchVariables": true
},
"files": [
"./src/hello.ts"
],
"include": [
"src/**/*"
],
"exclude": [
"/path/to/dist"
]
}
めちゃくちゃ増えましたね…。
Node.js 20のtsconfig.jsonの内容を見ると、strictがtrueになっているのでここが効いているんでしょうね。
{ "$schema": "https://json.schemastore.org/tsconfig", "display": "Node 20", "_version": "20.1.0", "compilerOptions": { "lib": ["es2023"], "module": "node16", "target": "es2022", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "moduleResolution": "node16" } }
https://github.com/tsconfig/bases/blob/ebe629c2857d386a0bc2c5d60cab18b9f1a425d0/bases/node20.json
ではここに、さらにRecommendedも追加してみましょう。Node.js 20と同時に指定します。
インストール。
$ npm i -D @tsconfig/recommended
バージョン。
"devDependencies": { "@tsconfig/node20": "^20.1.4", "@tsconfig/recommended": "^1.0.7", "@types/node": "^20.14.8", "typescript": "^5.5.4" }
Node.js 20とはまったくバージョン体系が違いますね…。というか、Node.jsの他のバージョンを見るとランタイムのバージョンを反映してそうな
感じがします。
tsconfig.jsonのextendsに追加してみます。
tsconfig.json
{ "extends": [ "@tsconfig/recommended/tsconfig.json", "@tsconfig/node20/tsconfig.json" ], "compilerOptions": { "baseUrl": "./src", "outDir": "dist" }, "include": [ "src/**/*" ] }
最終結果。
$ npx tsc --showConfig
{
"compilerOptions": {
"target": "es2022",
"module": "node16",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"lib": [
"es2023"
],
"moduleResolution": "node16",
"baseUrl": "./src",
"outDir": "./dist",
"moduleDetection": "force",
"allowSyntheticDefaultImports": true,
"resolvePackageJsonExports": true,
"resolvePackageJsonImports": true,
"useDefineForClassFields": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"alwaysStrict": true,
"useUnknownInCatchVariables": true
},
"files": [
"./src/hello.ts"
],
"include": [
"src/**/*"
],
"exclude": [
"/path/to/dist"
]
}
差を見ると、この組み合わせではforceConsistentCasingInFileNamesがtrueになったくらいですね。RecommendedとNode.js 20で
かなり重複していそうです。
Recommendedの中身を見ると実際そんな感じでしたが、moduleがcommonjsなのでこの組み合わせとする場合はNode.js 20を後ろに
指定した方がよさそうですね。extendsで複数した場合にオプションが重複した場合は、後ろに置いた内容の方で上書きされるので。
{ "compilerOptions": { "target": "es2016", "module": "commonjs", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true }, "display": "Recommended", "$schema": "https://json.schemastore.org/tsconfig" }
こんな感じでしょうか。
あとはStrictestも見た方がいいかもしれません。
https://github.com/tsconfig/bases/blob/ebe629c2857d386a0bc2c5d60cab18b9f1a425d0/bases/strictest.json
おわりに
TSConfig Basesを使って、tsconfig.jsonの推奨設定を確認してみました。
これらの設定を直接使うことがあるかはわかりませんが、tsconfig.jsonの設定をどうしたらいいか悩むことは多い気がするので、このあたりの
ファイルを参考にできることを覚えておいてもいいのではないかなと思います。