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

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

2022/4/14 min read
..
hero image

はじめに

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

環境構築

次のバージョンで検証されました。

1
@vitejs/create-app@2.4.5
bash

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

1
2
3
yarn create @vitejs/app <project-name> --template vue-ts
cd <project-name>
yarn
bash

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

⤵️ この作業は不要になりました。

Typescript にする

続いてプロジェクトを Typescript 化しましょう。といっても Vue3 からはデフォルトで Typescript が使えるので次の3つを行うだけです。

1.すべての.vueファイルのscriptタグにlang="ts"を追記します。 2.main.jsmain.tsに変更します。 3.index.htmlの script タグの src を/src/main.tsに変更します。

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

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

VSCode を使っている場合は、main.tsts(2307) エラーが出ているはずです。

これを解消するには、vue 用の型宣言ファイルを用意します。

1
2
3
4
5
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.tsts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
"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.jsonjson

これで Typescript 化は終了です。

ESLint を導入する

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

1
yarn add -D eslint eslint-plugin-vue @vue/eslint-config-typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin
bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"root": true,
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"plugin:vue/vue3-recommended",
"eslint:recommended",
"@vue/typescript/recommended"
],
"parserOptions": {
"ecmaVersion": 2021
},
"plugins": [
],
"rules": {
}
}
.eslintrcjson

これではエラーになってしまうので、型定義を修正します。

1
2
3
4
5
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.tsts

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

1
2
3
"scripts": {
"lint:script": "eslint --ext .ts,vue --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,vue}": "eslint --fix"
}
}
package.jsonjson

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

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

Prettier を設定する

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

1
yarn add -D prettier eslint-plugin-prettier @vue/eslint-config-prettier
bash
1
2
3
4
5
{
"singleQuote": true,
"semi": false,
"vueIndentScriptAndStyle": true
}
.prettierrcjson

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

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

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

1
yarn prettier -w -u .
bash

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

1
2
3
4
5
6
{
"lint-staged": {
"*.{ts,vue}": "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.jsonを編集して、コマンドと lint-staged を設定します。

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

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

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

Path Alias を設定する

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

1
2
3
4
5
6
7
8
9
10
11
12
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.tsts

また、 tsconfig.json も設定します。

1
2
3
4
5
6
7
8
9
{
"compilerOptions": {
//...
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
tsconfig.jsonjson

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

1
2
3
<script lang="ts">
import HelloWorld from '@/components/HelloWorld.vue'
</script>
App.vuehtml

vue-tsc で template の静的チェックをする

vue-tsc で template タグへも静的チェックを行えます。 テンプレート生成時にインストールされていますが、@vue/runtime-dom@3.1.4 の時点では、 tsconfig.jsonskipLibChecktrue になっていないと動作しません。

1
2
3
4
5
6
{
"compilerOptions": {
//...
"skipLibCheck": true
},
}
tsconfig.jsonjson
1
2
3
4
5
6
{
"scripts": {
//...
"lint:markup": "vue-tsc --noEmit",
}
}
package.jsonjson

これは @vue/runtime-dom の型定義にエラーがあるのでそれを回避する目的で行います。

また、静的チェックは Vue ファイルが増加するとかなり時間がかかるようになるため、コミット前ではなく CI で実行することをおすすめします。

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


Edit this page on GitHub

Other Article

Comments