ちいさなTypeScriptプロジェクトのテンプレ(esbuild,tsx,Rome,Vitest)

これは [ZOZO Advent Calendar 2022](https://qiita.com/advent-calendar/2022/zozo) カレンダー Vol.6 の 24日目の記事です。

「ちょっとコード書きたいけどJavaScriptはな」みたいなことがあると思いますが、TypeScriptとか ESLintとかPrettierとかJestとか...セットアップが面倒ですよね。

ヌルッとちいさく始める私の私による私のためのテンプレートを紹介します。

<details><summary>結論</summary>

~~Denoを使いましょう~~

```
npm i -D esbuild tsx rome vitest
```

```JSON:.vscode/settings.json
{
  "editor.defaultFormatter": "rome.rome",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll": true,
    "source.organizeImports": true
  }
}
```

```JSON:rome.json
{
  "$schema": "./node_modules/rome/configuration_schema.json",
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  },
  "formatter": {
    "enabled": true
  }
}
```

</details>

## TypeScript → esbuild/tsx with VSCode

ヌルッとちいさくはじめるときにtsconfig.jsonは仰々しいので作りません。

型チェックもVSCode組み込みの機能で概ね問題ないでしょう。

TypeScriptがとにかく実行できればいい場合は、[tsx](https://github.com/esbuild-kit/tsx)を使います。(ts-nodeは遅いので...)

```
npm i -D tsx
```

https://qiita.com/ssssota/items/115a906e960bcfabb46b

JavaScriptへのトランスパイルが必要な場合は、要件次第ですがとりあえず[esbuild](https://esbuild.github.io/)を使っておきます。
バンドルからminify、HTTPサーバーなどコミコミでついてきます。

```
npm i -D esbuild
```

```JSON:package.json
{"scripts": { "build": "esbuild --bundle src/index.ts" }}
```

最初から[Deno](https://deno.land/manual/advanced/typescript)を使うのもありかもしれません。

## ESLint/Prettier → Rome

ヌルッとちいさくはじめるときにESLintとPrettierは仰々しいので使いません。が、最低でもフォーマッターくらいは欲しいです。

Rust製の[Rome](https://rome.tools/)がすでにある程度使えるようになっているのでそちらを使います。Lintの機能もあります。なんと[VSCode拡張](https://marketplace.visualstudio.com/items?itemName=rome.rome)も十分に動きます。

ルールが拡張したくなったらESLintを素直に使いましょう。

```
npm i -D rome && npx rome init
```

```JSON:.vscode/settings.json
{
  "editor.defaultFormatter": "rome.rome",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll": true,
    "source.organizeImports": true
  }
}
```

```JSON:rome.json
{
  "$schema": "./node_modules/rome/configuration_schema.json",
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  },
  "formatter": {
    "enabled": true
  }
}
```

[dprint](https://dprint.dev/)や[Deno](https://deno.land/manual/tools)という選択肢もあります。
dprintはJSONなど他の言語もフォーマットしたい場合は選択肢に入れても良いでしょう。
Denoを使う場合は、最初からそれでいきましょう。

## Jest → Vitest

ヌルッとちいさくはじめるときにJestとTypeScriptの設定は仰々しいのでやりません。

VitestがTypeScriptでもよしなにテストを実行できて便利です。
ほぼZero-configでテストを書き始めることができます。
JS-DOMやtesting-libraryも設定を少し書けばちゃんと動くようになってます。

```
npm i -D vitest
```

```JSON:package.json
{"scripts": { "test": "vitest --run", "watch": "vitest" }}
```

[Deno](https://deno.land/manual/basics/testing)もいいでしょう。

## Vite

UIの開発が含まれる場合、Viteを使いましょう。React, Vue.js, Svelteなどはデフォルトでテンプレートがついているので以下のコマンドですぐに開発が始められます。

```
npm create vite
```

## まとめ

Node.jsのツールチェーンで活用する予定がなかったり、フロントエンドを開発しない場合の「雑に書いてみるTypeScriptプロジェクト」はDenoが便利です。

Node.jsやフロントエンド開発が含まれる場合はesbuild, tsx, Rome, Vite(Vitest)などを使って高速前進しましょう。

## おまけ

上で紹介した中で、tsx,Vite,VitestはGo製のesbuildが内部的に利用されています。
Next.jsで有名なVercelは(Rust製)SWCを用いたTurbopackを開発しましたが、TypeScriptトランスパイラの戦いには目が離せません。

本記事で登場したパッケージの依存関係は簡単には以下のようになります。

```mermaid
flowchart LR
  esbuild -.developed with.-> Go([Go])
  tsx --depends on--> esbuild
  Vitest --depends on--> Vite
  Vite --depends on--> esbuild
```

```mermaid
flowchart LR
  Rust([Rust])
  subgraph Deno
    deno_lint
    deno_fmt
    deno_ast
  end
  Rome -.developed with.-> Rust
  dprint -.developed with.-> Rust
  Turbopack -.developed with.-> Rust
  SWC -.developed with.-> Rust
  Deno -.developed with.-> Rust
  Turbopack --depends on--> SWC
  dprint --depends on--> deno_ast
  deno_fmt --depends on--> dprint
  deno_ast --depends on--> SWC
  deno_lint --depends on--> deno_ast
```