TypeScript + ESModules の開発環境をシュッと作る
ほぼ設定なしで TypeScript + ESModules の開発環境をシュッと作る時のレシピです。
プロジェクトの作成
はじめに以下のコマンドで package.json
を作成します。
npm init -y
ESModules として扱いたいので package.json
に "type": "module"
を追加します。
{
"name": "ts-esmodules",
"version": "1.0.0",
"description": "",
+ "type": "module",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
TypeScript のインストール
以下のコマンドで TypeScript とその他必要なパッケージをインストールします。
npm i -D typescript @tsconfig/node-lts-strictest-esm ts-node
@tsconfig/node-lts-strictest-esm
は TSConfig bases から提供されているパッケージの 1 つです。TSConifg bases はフレームワークごとに最適な設定の TSConfig を公開しているレポジトリです。それぞれの TSConfig は npm パッケージとして提供されています。今回使用している @tsconfig/node-lts-strictest-esm
は Node LTS + ESM かつ厳格な設定となっています。
TSConfig bases は tsconfig.json
を作成して extends
にパッケージを記述するだけで設定を適用できます。
{
"extends": "@tsconfig/node-lts-strictest-esm"
}
TypeScript をそのまま実行するために ts-node を使います。ts-node
を ESModules で実行するためには esm
オプションが必要です。tsconfig.json
の "ts-node"
オプションに "esm": true
を追加します。
{
"extends": "@tsconfig/node-lts-strictest-esm",
+ "ts-node": {
+ "esm": true
+ }
}
コードの実行は早いほうが好きなのでトランスパイラに SWC を使用します。ts-node
は組み込みのオプションで SWC をサポートしています。SWC を使用するためには以下のパッケージをインストールします。
npm i -D @swc/core @swc/helpers regenerator-runtime
その後、tsconfig.json
の "ts-node"
オプションに "swc": true
を追加します。
{
"extends": "@tsconfig/node-lts-strictest-esm",
"ts-node": {
+ "swc": true,
"esm": true
}
}
ここまでで TypeScript を実行する環境が整いました。簡単なコードで試してみましょう。
export const add = (a: number, b: number) => a + b;
import { add } from "./calc.js";
console.log(add(1, 2));
ESModules の場合モジュールの import
ときに拡張子が必須となっているので注意が必要です。.ts
ファイルであったとしても必ず .js
として記載する必要があります。このあたりの問題は TypeScript 5.0 の --moduleResolution bundler で改善される見込みです。
package.json
に TypeScript を実行するコマンドを追加しましょう。
{
"scripts": {
"start": "ts-node src/main.ts"
},
}
これで問題なく実行できるはずです。
npm start
> [email protected] start
> ts-node src/main.ts
3
トランスパイラに SWC を指定しているため、実行時に型チェックを行いません。手癖として typecheck
スクリプトを追加しておくのがよいでしょう。
{
"scripts": {
"start": "ts-node src/main.ts",
"typecheck": "tsc --noEmit",
}
}
リンター・フォーマッター
綺麗なコードが好きなのでリンターとフォーマッターも導入します。以下のコマンドで対話的に ESLint を導入できます。
npm init @eslint/config
? How would you like to use ESLint? …
To check syntax only
❯ To check syntax and find problems
To check syntax, find problems, and enforce code style
? What type of modules does your project use? …
❯ JavaScript modules (import/export)
CommonJS (require/exports)
None of these
? Which framework does your project use? …
React
Vue.js
❯ None of these
? Does your project use TypeScript? › Yes
? Where does your code run? … (Press <space> to select, <a> to toggle all, <i> to invert selection)
Browser
✔ Node
? What format do you want your config file to be in? …
❯ JavaScript
YAML
JSON
@typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest eslint@latest
? Would you like to install them now? › Yes
? Which package manager do you want to use? …
❯ npm
yarn
pnpm
コマンドの実行が完了すると eslintrc.cjs
ファイルが作成されます。おすすめの設定が入っているので、設定を変更せずともこのまま使い始めることができます。
module.exports = {
"env": {
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
}
}
続いて Prettier を導入します。ESLint と組み合わせ使う場合にはルールの競合を防ぐため eslint-config-prettier
パッケージも必要です。
npm i -D prettier eslint-config-prettier
デフォルトの設定で Prettier の設定ファイルである .prettierrc
を作成します。
echo {}> .prettierrc
eslintrc.cjs
の extends
に prettier
を追記します。extends
は最後のルールが優先されるので必ず prettier
を一番最後にする必要があります。
module.exports = {
env: {
es2021: true,
node: true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
+ "prettier",
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
plugins: ["@typescript-eslint"],
rules: {},
};
リントとフォーマットを実行するスクリプトを追加します。それぞれ単にコードスタイルをチェックするだけのスクリプトと、修正まで行うスクリプトどちらも用意しておくと便利です。
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
},
}
テスト
テスト用のライブラリとして Vitest を使用します。Jest と互換性のある構文を持ちながら、ゼロコンフィグで始めることができます。
npm i -D vitest
簡単なテストコードを書いてみましょう。
import { add } from "./calc.js";
import { describe, it, expect } from "vitest";
describe("add", () => {
it("should add two numbers", () => {
expect(add(1, 2)).toBe(3);
});
});
package.json
にテストスクリプトを追加します。
{
"scripts": {
"test": "vitest"
},
}
設定なしですぐに実行できます。
npm test
VSCode
プロジェクトのルートディレクトリに .vscode
ディレクトリを設定しておくと、拡張機能や設定ファイルを共有できるので便利です。.vscode/extensions.json
ではプロジェクトでおすすめの拡張機能を記述できます。
VSCode の拡張子の画面から歯車アイコン → Add to Workspace Recommendations で簡単に拡張子を設定に追加できます。
おすすめの拡張子として ESLint,Prettier,Vitest の 3 つを追加しておきました。
{
"recommendations": [
"zixuanchen.vitest-explorer",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
.vscode/settings.json
ではプロジェクトで適用される設定を記述します。この設定は個人の設定よりも優先されます。ここでは、デフォルトのフォーマットとして Prettier を使用する設定と、Vitest の拡張子を有効にする設定を入れました。
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"vitest.enable": true
}