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

はじめに
Vite は Vue.js の作者の Evan You 氏が開発しているビルドツールです。 ネイティブの ES Module のインポートを利用し、バンドル不要で高速に動作する開発環境を提供します。 Vue3 はもちろん、React や Preact も対応しています。
今回はそんな Vite を使って、Vue3 プロジェクトの環境構築をします。
できあがったテンプレートはこちらにあります。
やること
vue/cli の default テンプレートに近づけることを目標に、最低限開発に必要なツールを導入していきます。 ツールを個別に導入できるよう、それぞれ順を追って説明しています。
Typescript- ESLint
- Prettier
- Stylelint
- husky と lint-staged
- Path Alias
- vue-tsc
環境構築
次のバージョンで検証されました。
@vitejs/create-app@2.4.5
まずは、vite のテンプレートを展開しましょう。
YarnNPM
yarn create @vitejs/app <project-name> --template vue-tscd <project-name>yarn
開発サーバーを立ち上げるとその速さに感動します。
⤵️ この作業は不要になりました。
Typescript にする
続いてプロジェクトを Typescript 化しましょう。といって��� Vue3 からはデフォルトで Typescript が使えるので次の3つを行うだけです。
1.すべての.vueファイルのscriptタグにlang="ts"を追記します。 2.main.jsをmain.tsに変更します。 3.index.htmlの script タグの src を/src/main.tsに変更します。
これで開発サーバーを立ち上げると、問題なく実行できるのが確認できます。
実際はこれだけでも動きますが、エディター上でのユーザーエクスペリエンスを向上させるために、さらに設定を加えます。
VSCode を使っている場合は、 main.tsでts(2307)エラーが出ているはずです。
これを解消するには、vue 用の型宣言ファイルを用意します。
declare module '*.vue' { import type { DefineComponent } from 'vue' const component: DefineComponent<Record<string,unknown>, Record<string,unknown>, unknown> export default component}
src/shims-vue.d.ts
{ "compilerOptions": { "target": "es5", "module": "esnext", "strict": true, "jsx": "preserve", "importHelpers": true, "moduleResolution": "node", "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "sourceMap": true, "baseUrl": ".", "paths": { "/@/*": [ // /から始まるようにします "src/*" ] }, "lib": [ "esnext", "dom", "dom.iterable", "scripthost" ] }, "include": [ "src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", ], "exclude": [ "node_modules" ]}
tsconfig.json
これで Typescript 化は終了です。
ESLint を導入する
リンターのない開発は厳しいので、必ず導入しましょう。
YarnNPM
yarn add -D eslint eslint-plugin-vue @vue/eslint-config-typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin
{ "root": true, "env": { "browser": true, "es2021": true, "node": true }, "extends": [ "plugin:vue/vue3-recommended", "eslint:recommended", "@vue/typescript/recommended" ], "parserOptions": { "ecmaVersion": 2021 }, "plugins": [ ], "rules": { }}
.eslintrc
これではエラーになってしまうので、型定義を修正します。
declare module '*.vue' { import type { DefineComponent } from 'vue' const component: DefineComponent<Record<string,unknown>, Record<string,unknown>, unknown> export default component}
src/shims-vue.d.ts
package.jsonのscriptにリント用のコマンドを用意するとのちのち楽です。
"scripts": { "lint:script": "eslint --ext .ts,vue --ignore-path .gitignore ."}
package.json
個人的には、fix したくない場��������ので、--fixは外から付けるようにしています。
さてこれを実行させましょう。
YarnNPM
yarn lint:script --fix
VSCode ユーザーは以下の設定もすることで、自動フォーマットを効かせることができます。 ESLint の拡張が必要なので、なければここを参考にインストールしてください。
{ "editor.codeActionsOnSave": { "source.fixAll": true }}
.vscode/settings.json
これによって保存時にフォーマットできました。
husky と lint-staged を設定する
コミット前に、静的チェックを走らせ、エラーコードをコミットできない仕組みにしましょう。
YarnNPM
yarn add -D husky lint-staged
package.jsonに次を追加します。
{ "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{ts,vue}": "eslint --fix" }}
package.json
これによって、コミット前にコミットファイルのうち該当する拡張子のファイルに対し、ESLint が走ります。
もちろんリントエラーの場合はコミットがキャンセルされます。
Prettier を設定する
Prettier にプロジェクト全体のフォーマットを任せましょう。 また、Typescript のコードでは、セミコロンは視認性が悪くなるため、Prettier で自動的に削除しましょう。
YarnNPM
yarn add -D prettier eslint-plugin-prettier @vue/eslint-config-prettier
{ "singleQuote": true, "semi": false, "vueIndentScriptAndStyle": true}
.prettierrc
ESLint と Prettier を併用する場合、ルールのバッティングがあるため、.eslintrcを修正します。
{ "extends": [ "plugin:vue/vue3-recommended", "eslint:recommended", "@vue/typescript/recommended", // 他のルールの下に追加 "@vue/prettier", "@vue/prettier/@typescript-eslint" ]}
.eslintrc
コマンドによってフォーマッターを実行できます。
YarnNPM
yarn prettier -w -u .
コミット前に自動フォーマットを適用させたいので、lint-stagedにその設定を加えます。
{ "lint-staged": { "*.{ts,vue}": "eslint --fix", "*": "prettier -w -u" // prettierは一番最後にします }}
package.json
VSCode ユーザーは次の設定によって、自動的にフォーマットできます。 また、例によって拡張が必要なので、なければこちらを参考にインストールしてください。
{ "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode"}
.vscode/settings.json
Stylelint を設定する
スタイルもリント対象にしましょう。
YarnNPM
yarn add -D stylelint stylelint-config-recommended stylelint-config-standard
{ "extends": ["stylelint-config-recommended", "stylelint-config-standard"]}
.stylelintrc
package.jsonを編集して、コマンドと lint-staged を設定します。
{ "scripts": { "lint:style": "stylelint src/**/*.{css,scss,vue}" }, "lint-staged": { "*.{ts,tsx}": "eslint --fix", "*.{css,scss,vue}": "stylelint --fix", "*": "prettier -w -u" }}
package.json
VSCode ユーザーは次の設定によって、自動的にフォーマットできます。 拡張が必要なので、なければこちらを参考にインストールしてください。
長くなりましたがこれでリンターとフォーマッターの基本的な設定は終了です。
Path Alias を設定する
モジュールの import はデフォルトでは相対パスを指定しますが、alias を設定して常に同じルートを参照したいです。
import { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'import { resolve } from 'path' export default defineConfig({ resolve: { alias: { '@': resolve(__dirname, 'src') } }, plugins: [vue()]})
vite.config.ts
また、 tsconfig.json も設定します。
{ "compilerOptions": { //... "baseUrl": ".", "paths": { "@/*": ["./src/*"] } }}
tsconfig.json
これで alias の設定ができました。こんな感じで使います。
<script lang="ts"> import HelloWorld from '@/components/HelloWorld.vue'</script>
App.vue
vue-tsc で template の静的チェックをする
vue-tsc で template タグへも静的チェックを行えます。 テンプレート生成時にインストールされていますが、@vue/runtime-dom@3.1.4 の時点では、 tsconfig.jsonの skipLibCheck が true になっていないと動作しません。
{ "compilerOptions": { //... "skipLibCheck": true },}
tsconfig.json
{ "scripts": { //... "lint:markup": "vue-tsc --noEmit", }}
package.json
これは @vue/runtime-dom の型定義にエラーがあるので���れを回避する目的で行います。
また、静的チェックは Vue ファイルが増加するとかなり時間がかかるようになるため、コミット前ではなく CI で実行することをおすすめします。
以上で最低限の環境が構築できました。