ViteでPreactのTypescript環境を構築する

No bundleツールのViteを使って、TypescriptベースのPreactの環境を構築します。ESLintやPrettierの設定もあわせて行います。

2021/10/104 min read
..
hero image

はじめに

Vite は Vue.js の作者の Evan You 氏が開発しているビルドツールです。 ネイティブの ES Module のインポートを利用し、バンドル不要で高速に動作する開発環境を提供します。 Vue3 はもちろん、React や Preact も対応しています。 今回はそんな Vite を使って、Preact プロジェクトの環境構築をします。

できあがったテンプレートはこちらにあります。

やること

preact/cli の default テンプレートに近づけることを目標に、最低限開発に必要なツールを導入していきます。 ツールを個別に導入できるよう、それぞれ順を追って説明しています。

  • Typescript
  • ESLint
  • Prettier
  • Stylelint
  • husky と lint-staged
  • Path Alias

環境構築

まずは、vite のテンプレートを展開しましょう。

1
2
3
yarn create vite-app <project-name> --template preact
cd <project-name>
yarn
bash

開発サーバーを立ち上げるとその速さに感動します。

Typescript にする

続いてプロジェクトを Typescript 化しましょう。最小限の構成では次の2つを行うだけです。

1.すべての.jsxファイルを.tsxにします。 2.index.htmlの script タグの src を/src/main.tsxに変更します。

これで開発サーバーを立ち上げると、問題なく実行できるのが確認できます。

実際はこれだけでも動きますが、エディター上でのユーザーエクスペリエンスを向上させるために、さらに設定を加えます。

tsconfig.jsonをプロジェクトルートに設置します。これでエディターに Typescript プロジェクトであることを認識させます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"compilerOptions": {
"target": "esnext",
"lib": ["DOM", "DOM.Iterable", "esnext"],
"allowJs": false,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment"
},
"include": ["src"]
}
tsconfig.jsonjson

VSCode ではこの時点で、.tsxファイルにエラーが表示されているので、これを修正します。全ての.tsxファイルに次の一文を加えます。

1
import { h } from 'preact'
ts

またFragmentを使っている場合は、更にそれもインポートします。

1
import { h, Fragment } from 'preact'
ts

次に、エントリーポイントであるmain.tsxを修正します。 Typescript になったことで、型エラーが検出されています。 document.getElementByIdは戻り値がHTMLElementまたはnullなため、null チェックを入れてあげます。

`index.html`の id に app が必ず存在するなら、`Non-null assertion operator`も使えます。
1
2
3
4
const el = document.getElementById('app')
if (el) {
render(<App />, el)
}
main.tsxtsx

続いてvite.config.jsに変更を加えます。

1
2
3
4
5
6
7
const config = {
jsx: {
factory: 'h',
fragment: 'Fragment'
},
plugins: [preactRefresh()]
}
vite.config.jsts

最小構成で Typescript 化できました。以下は、やらなくても問題ありません。

.jsファイルの撲滅のため、vite.config.js.tsに変更しましょう。また、ES Module 形式に変更し、プロジェクト全体の統一感を高めましょう。

vite.config.tsは以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
import preactRefresh from '@prefresh/vite'
import type { UserConfig } from 'vite'
const config: UserConfig = {
jsx: {
factory: 'h',
fragment: 'Fragment',
},
plugins: [preactRefresh()],
}
export default config
vite.config.tsts

これで Typescript 化は終了です。

ESLint を導入する

リンターのない開発は厳しいので、必ず導入しましょう。

1
yarn add -D eslint eslint-config-preact @typescript-eslint/parser typescript
bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"preact"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {}
}
.eslintrcjson

package.jsonscriptにリント用のコマンドを用意するとのちのち楽です。

1
2
3
"scripts": {
"lint:script": "eslint --ext .ts,tsx --ignore-path .gitignore ."
}
package.jsonjson

個人的には、fix したくない場面もあるので、--fixは外から付けるようにしています。

さてこれを実行させましょう。

1
yarn lint:script --fix
bash

VSCode ユーザーは以下の設定もすることで、自動フォーマットを効かせることができます。 ESLint の拡張が必要なので、なければここを参考にインストールしてください。

1
2
3
4
5
{
"editor.codeActionsOnSave": {
"source.fixAll": true
}
}
.vscode/settings.jsonjson

これによって保存時にフォーマットできました。

husky と lint-staged を設定する

コミット前に、静的チェックを走らせ、エラーコードをコミットできない仕組みにしましょう。

1
yarn add -D husky lint-staged
bash

package.jsonに次を追加します。

1
2
3
4
5
6
7
8
9
10
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{ts,tsx}": "eslint --fix"
}
}
package.jsonjson

これによって、コミット前にコミットファイルのうち該当する拡張子のファイルに対し、ESLint が走ります。

もちろんリントエラーの場合はコミットがキャンセルされます。

Prettier を設定する

Prettier にプロジェクト全体のフォーマットを任せましょう。 また、Typescript のコードでは、セミコロンは視認性が悪くなるため、Prettier で自動的に削除しましょう。

1
yarn add -D prettier eslint-config-prettier
bash
1
2
3
4
5
{
"trailingComma": "es5",
"semi": false,
"singleQuote": true
}
.prettierrcjson

ESLint と Prettier を併用する場合、ルールのバッティングがあるため、.eslintrcを修正します。

1
2
3
4
5
6
7
8
9
{
"extends": [
"eslint:all",
"preact",
// 他のルールの下に追加
"prettier",
"prettier/@typescript-eslint"
]
}
.eslintrcjson

コマンドによってフォーマッターを実行できます。

1
yarn prettier -w -u .
bash

コミット前に自動フォーマットを適用させたいので、lint-stagedにその設定を加えます。

1
2
3
4
5
6
{
"lint-staged": {
"*.{ts,tsx}": "eslint --fix",
"*": "prettier -w -u" // prettierは一番最後にします
}
}
package.jsonjson

VSCode ユーザーは次の設定によって、自動的にフォーマットできます。 また、例によって拡張が必要なので、なければこちらを参考にインストールしてください。

1
2
3
4
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
.vscode/settings.jsonjson

Stylelint を設定する

スタイルファイルもリント対象にしましょう。

1
yarn add -D stylelint stylelint-config-recommended stylelint-config-standard
bash
1
2
3
{
"extends": ["stylelint-config-recommended", "stylelint-config-standard"]
}
.stylelintrcjson

package.jsoonを編集して、コマンドと lint-staged を設定します。

1
2
3
4
5
6
7
8
9
10
{
"scripts": {
"lint:style": "stylelint src/**/*.{css,scss}"
},
"lint-staged": {
"*.{ts,tsx}": "eslint --fix",
"*.{css,scss}": "stylelint --fix",
"*": "prettier -w -u"
}
}
package.jsonjson

VSCode ユーザーは次の設定によって、自動的にフォーマットできます。 拡張が必要なので、なければこちらを参考にインストールしてください。

長くなりましたがこれでリンターとフォーマッターの基本的な設定は終了です。

Path Alias を設定する

モジュールの import はデフォルトでは相対パスを指定しますが、alias を設定して常に同じルートを参照したいです。

vite.config.tstsconfig.json変更して alias を設定しましょう。

Key は`/`から始まらなければなりません。
1
2
3
4
5
6
7
8
9
10
import { join } from 'path'
import type { UserConfig } from 'vite'
const config: UserConfig = {
alias: {
'/@/': join(__dirname, 'src'),
}
}
export default config
vite.config.tsts
1
2
3
4
5
6
7
8
9
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"/@/*": ["src/*"]
}
},
"include": ["src"]
}
tsconfig.jsonjson

これで alias の設定ができました。こんな感じで使います。

1
import { App } from '/@/app'
main.tsxtsx

/から始まらなければならないのが、少し違和感ありますが、パッケージ名の alias との兼ね合いみたいです。 詳しくはこちらを参照ください。

以上で最低限の環境が構築できました。


Edit this page on GitHub

Other Article

Comments