Устанавливаем Vue+TS:
# Ставим Vue + TypeScript:
pnpm create vite@latest frontend -- --template vue-ts
# Это просто удобная обёртка над:
pnpm dlx create-vite@latest frontend --template vue-ts
# Или:
pnpm add create-vite --save-dev
pnpm exec create-vite frontend --template vue-ts
pnpm remove create-vite
Как запустить сервер Vue в режиме разработки из папки frontend:
# с помощью pnpm:
pnpm --dir frontend run dev
# с помощью npm:
npm run dev --prefix frontend
Создаём компонент Govno.vue:
// frontend/src/components/Govno.vue
<script setup>
import { ref } from 'vue';
const count = ref(0);
</script>
<template>
<h1>Говно</h1>
<p>Счётчик: {{ count }}</p>
<button v-on:click="count++">Кнопка</button>
</template>
<style scoped>
</style>
Подключаем компонент Govno в App.vue:
// frontend/src/App.vue
<script setup lang="ts">
import Govno from './components/Govno.vue'
</script>
<template>
<Govno />
</template>
Подключаем главные компонент App.vue в main.ts:
// frontend/src/main.ts
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
createApp(App).mount('#app')
После подключения компонента Govno.vue в App.vue, VSCodium начнёт ругаться:
Could not find a declaration file for module './components/Govno.vue'.
'/home/mark/projects/vue/pupa/frontend/src/components/Govno.vue' implicitly has an 'any' type.
Нужно просто объявить типизацию для .vue-файлов.
Для этого создадим env.d.ts:
// frontend/src/env.d.ts
/// <reference types="vite/client" />
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
Приблизительное содержание tsconfig.app.json:
// frontend/tsconfig.app.json
{
"compilerOptions": {
"types": ["vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"]
}
Тут надо, чтобы в раделе "include" был включён наш созданный ранее env.d.ts.
Вот мой дефолтный tsconfig.app.json, созданный Vite (тут уже включён наш файл env.d.ts):
// frontend/tsconfig.app.json
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"types": ["vite/client"],
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}
Ставим типы для Node
# Ставим типы для Node:
pnpm add @types/node --save-dev
Чуть выше я установил типы для Node.js. Теперь в node_modules/@types/node лежат файлы с описанием всех встроенных модулей Node.js (fs, path, process, Buffer и т. д.).
Теперь в tsconfig.json мы говорим: «Подключай только типы, относящиеся к Node.js.»:
// tsconfig.json
"types": ["node"],
Если не указать тип (то есть просто удалишь строку внутри массива: "types": []), TypeScript сам попробует подключить все типы из node_modules/@types/. Это тоже будет работать, но иногда может подключить лишние типы (например, @types/dom от какой-то другой зависимости). Поэтому в серверных проектах на Node.js принято явно указывать: "node".
# Ставим Express и типы для него:
pnpm add express --save-prod
pnpm add @types/express --save-dev
Подключение ts-файлов:
// tsconfig.json
{
"files": ["./backend/src/server.js"],
"compilerOptions": {
"rootDir": "./backend/src",
"outDir": "./backend/dist"
...
}
}