【2023年末】tsconfigの設定値整理

# はじめに

ご無沙汰しております。うらさくと申します
この記事は[TechCommit Advent Calendar 2023]()の7日目の記事です
まさかの3連投です

# 記事の概要

今年度から合流し、最初に行ったのがプロジェクトのconfigファイル整理でした

正直雰囲気でやっていたところなので、細かいところが全く分からず、結構苦戦したのでまとめてみました

もちろん項目書いていたら日が暮れてしまうので、よく使うであろうところやつまづきやすいところを抜粋しました

こういう類のものはすぐに移り変わって廃れてしまいがちですが、現在のどなたかの参考になれば幸いです

# tsconfigとは

>TypeScriptファイル（.tsファイル）をJavaScriptコードへコンパイルする際のコンパイルオプションを記述するファイルであり、 「TypeScriptがどのようにJavaScriptにコンパイルされるか」 を決定する、なくてはならない設定ファイル

## サンプル

```
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "commonjs",
    "declaration": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": false,
    "inlineSourceMap": true,
    "inlineSources": true,
    "experimentalDecorators": true,
    "strictPropertyInitialization": false,
    "typeRoots": ["./node_modules/@types"]
  },
  "exclude": ["node_modules", "cdk.out"]
}
```

# 各項目の説明

## target

- TypeScriptからJavaScriptにコンパイルされる際にどのバージョンのJavaScriptで出力するかを指定する

    - es3, es5, es6/es2015, es2016, es2017, es2018, es2019, es2020, es2021, es2022, esnextなどが選択可能

    - デフォルトはes3

- Nodeのバージョンごとに推奨設定がある（18の場合はes2022）

    - node.greenを確認

## module

- TypeScriptからJavaScriptにコンパイルされる際に、どのモジュールパターンにするかを指定する

    - none, commonjs, amd, system, umd, es6, es2015, es2020, es2022, esnext, node16, nodenextなどが選択可能

    - デフォルトはtargetの値によって異なる

        - targetがes3/es5のときmoduleはcommonjs
        - それ以外のtargetのときはes6/es2015

- 通常バックエンドではcommonjs、フロントエンドではes系（EMS）が利用されているらしい

## CJSとEMS

### CommonJS（CJS）

> CommonJSとは、サーバーサイドなどのウェブブラウザ環境外におけるJavaScriptの各種仕様を定めることを目標としたプロジェクトである。

- 他モジュールを呼び出す際はrequireで呼び出す。

```
const functions = require('./libs/functions')
functions.hoge()
```

- 利用先の代表例はNode.js

- Node.jsはデフォルトで全てのモジュールをCommonJSで扱うが、v16以降はでES Modulesに対応している

### ESModule（ESM）

> ECMAScript（エクマスクリプト）は、Ecma Internationalのもとで標準化手続きが行われているJavaScriptの規格

- ウェブブラウザがECMAScriptをサポートしている。

- Node.jsでESMを利用する際は以下どちらかの設定が必要

1. package.jsonに、"type": "module"を設定する
2. 拡張子を.mjsに変える

（Node14以前のバージョンでは--input-type=moduleオプションを付けて実行する必要がある）

### ES Modulesが推奨されている理由

言語レベルの文法や、ブラウザサポート、デフォルトでstrictモード、非同期import、トップレベルでのawaitの使用、静的解析の向上、ツリーシェイキングなど様々な利点がある

Node.jsでも16以降は対応され、CommonJSで書かれたモジュールも呼べること、さらにnode.js 16.x は、2023/09/11 でサポート終了となり、Lambdaでは mjs がデフォルトになっているということからも、ESMの方に流れが向いているのではないかと感じている

## lib

- 指定した target には使いたい機能がないときに指定する

    - 必須ではない

    - target を指定すればそのバージョンで使われているライブラリは自動的に追加されるので、そこに実装されていないライブラリの追加や、必要がないライブラリを除外に使う

## moduleResolution

- Import 対象のソースコード・型定義ファイルをどのように検索するかを指定する

- classic, node10/node, node16, nodenext, bundlerなどが選択可能

- デフォルトはmoduleの値によって異なる

| module | moduleResolution |
|:-----------|------------:|
| amd/umd/system/es6/es2015       | classic        |
| node16     | node16      |
| nodenext       | nodenext        |
| それ以外         | node          |

- nodeの場合は拡張子を省略した相対パス探索が行われるが、node16ではimport時の拡張子省略が許容されない

参考文献

https://www.typescriptlang.org/ja/tsconfig 

https://gmo-aozora.hatenablog.com/entry/2023/02/17/110732 

https://zenn.dev/chida/articles/bdbcd59c90e2e1 

https://quramy.medium.com/typescript-%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E9%96%A2%E9%80%A3%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E6%95%B4%E7%90%86-efdf860a7c4 

https://blog.s2n.tech/articles/dont-use-moduleresolution-node#node--node10 

https://note.com/shift_tech/n/nfcf300645c9a 

https://github.com/tsconfig/bases