Настройка VueJS 3 Typescript + Vite

Это руководство о том, как настроить новый проект Vue 3 с вышеупомянутым техническим стеком, а также некоторыми дополнениями, которые действительно могут помочь в части DX (Developer Experience).

Рассмотрим такие вещи, как:

  • Editorconfig
  • ESLint
  • Husky и lint-staged
  • Алиасы путей
  • Статическая проверка template с помощью vue-tsc

Создание рабочей среды

Для начала создаём новый проект (заменяем <project-name> на название создаваемой папки):

npm create vite@latest <project-name> -- --template vue-ts

Параметр --template vue-ts указывает, что будет создан проект на vuejs с уже настроенным typescript

Переходим в созданную папку:

cd <project-name>

И устанавливаем зависимости:

npm i

Настройка Editorconfig

.editorconfig
root = true

[*]
indent_style = tab
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8

[*.min.*]
indent_style = ignore
trim_trailing_whitespace = false
insert_final_newline = ignore

[*.{md,txt}]
indent_style = space
indent_size = 4
trim_trailing_whitespace = false

[Makefile]
indent_style = tab

[CHANGELOG.md]
indent_size = false

Дополнительная настройка для VS CODE

Для автоматической правки кода в vs code добавляем расширение в список рекомендуемых:

.vscode/extensions.json
{
    "recommendations": [
        // ....
        "EditorConfig.EditorConfig",
    ]
}

Настройка ESLint

npm i -D eslint eslint-plugin-vue @vue/eslint-config-typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin vue-eslint-parser vue-tsc@latest
.eslintrc
{
    "root": true,
    "env": {
        "browser": true,
        "es2021": true,
        "node": true
    },
    "extends": [
        "plugin:vue/vue3-recommended",
        "eslint:recommended",
        "@vue/typescript/recommended"
    ],
    "parser": "vue-eslint-parser",
    "parserOptions": {
        "ecmaVersion": "latest",
        "parser": {
            "ts": "@typescript-eslint/parser",
            "<template>": "espree"
        },
        "sourceType": "module"
    },
    "plugins": [],
    "ignorePatterns": ["dist/**/*", "node_modules/**/*"],
    "rules": {
        "semi": ["error", "always"],
        "quotes": ["error", "double", { "avoidEscape": true, "allowTemplateLiterals": true }],
        "indent": ["error", "tab"],
        "vue/no-unused-vars": "error",
        "vue/html-indent": ["error", "tab"],
        "@typescript-eslint/no-explicit-any": "off"
    }
}

Это приведет к ошибке при сборке, поэтому мы изменим определение типа.

src/vite-env.d.ts
declare module "*.vue" {
    import type { DefineComponent } from "vue";
    const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>;
    export default component;
}

Теперь можем добавить в package.json скрипт для линтинга:

package.json
"scripts": {
    "lint:script": "eslint --ext .ts,vue --ignore-path .gitignore ."
}

Данный скрипт будет только проверять без фикса ошибок, если нужно автоматически исправить ошибки, то скрипт можно запустить так

npm run lint:script --fix

Дополнительная настройка для VS CODE

Для автоматической форматирования кода в vs code добавляем расширение в список рекомендуемых:

.vscode/extensions.json
{
    "recommendations": [
        // ....
        "dbaeumer.vscode-eslint",
    ]
}

Чтобы отформатировать файл при сохранении используем следующую настройку:

.vscode/settings.json
{
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    },
    "eslint.validate": [
        "javascript",
        "typescript",
        "vue"
    ],
    "eslint.options": {
        "ignorePath": ".gitignore"
    }
}

Настройка husky и lint-staged

Перед коммитов давайте запустим статическую проверку, чтобы убедиться, что вы не зафиксируете код содержащий ошибки.

npm i -D husky lint-staged

Добавляем следующее в package.json.

package.json
{
    "husky": {
        "hooks": {
            "pre-commit": "lint-staged"
        }
    },
    "lint-staged": {
        "*.{ts,vue}": "eslint --fix"
    }
}

Это приведет к тому, что ESLint будет запускаться и проверять все файлы перед каждым коммитом, и если будет найдена ошибка, то коммит будет отменён.

Настройка алиасов путей

Импорт модуля по умолчанию является относительным, но вы хотите установить псевдоним, чтобы всегда ссылаться на один и тот же корень.

npm i -D @types/node@18.8.0

Используется версия типов ноды 18.8.0 так как в версии 18.8.5 при анализе vue кода показывается ошибка у event, например у @click. Возможно в более новой версии это уже пофиксили.

vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { resolve } from "path";

export default defineConfig({
    resolve: {
        alias: {
            "@": resolve(__dirname, "src")
        }
    },
    plugins: [vue()]
});

Также изменим tsconfig.json.

tsconfig.json
{
    "compilerOptions": {
        //...
        "baseUrl": ".",
        "paths": {
            "@/*": ["./src/*"]
        }
    }
}

Теперь при импорте можно использовать псевдоним для пути:

<script setup lang="ts">
    import HelloWorld from '@/components/HelloWorld.vue'
</script>

Статическая проверка template с помощью vue-tsc

Вы можете статически проверять теги шаблона с помощью vue-tsc.

Он устанавливается при создании шаблона. Однако, начиная с @vue/runtime-dom@3.1.4, он не работает, если для параметра skipLibCheck в tsconfig.json не задано значение true.

tsconfig.json
{
    "compilerOptions": {
        //...
        "skipLibCheck": true
    },
}
package.json
{
    "scripts": {
        //...
        "lint:markup": "vue-tsc --noEmit",
    }
}

Рекомендуется запускать статические проверки в CI, а не перед фиксацией, поскольку статические проверки могут занимать довольно много времени по мере увеличения количества файлов Vue.