Files
nuxt4/readme.md
T
2026-05-03 07:26:12 +00:00

701 lines
17 KiB
Markdown

# Nuxt Workspace Template
Nuxt 4 template pre lokalny vyvoj vo VS Code na hoste. Repozitar obsahuje zakladnu aplikaciu s i18n, Nuxt UI, jednoduchym loggerom, volitelnou auth kostrou, OpenAPI-ready API vrstvou a predpripravenym workspace nastavenim pre lokalny vyvoj.
Dalsia dokumentacia:
- `quick_start.md`: rychly postup po vytvoreni projektu z template
- `programing_guide.md`: podrobny prehlad toho, co template poskytuje, ako sa to pouziva a ako sa to da rozsirovat
## Co je pripravene
- Nuxt `4.4.2`
- TypeScript `5.9.3`
- `pnpm` ako package manager
- `@nuxtjs/i18n` s jazykmi `sk` a `en`
- light, dark a system tema cez Nuxt color mode
- klientsky logger dostupny cez composable
- volitelna auth kostra s modmi `disabled`, `mock` a `userinfo`
- OpenAPI-ready API vrstva s generator skriptmi a wrappermi
- Nuxt UI ako predvolena komponentova vrstva
- `.vscode` konfiguracia pre vyvoj vo VS Code
- ESLint, Prettier a Vitest
## Pre koho je template
Template je vhodny ako vychodiskovy bod pre:
- dashboardy a interne aplikacie
- portalove aplikacie
- administracne rozhrania
- mensie a stredne Nuxt projekty, kde chces zacat rychlo, ale nie od nuly
## Struktura projektu
Najdolezitejsie casti repozitara:
- `app/pages`:
routovatelne stranky aplikacie
- `app/layouts`:
spolocny layout aplikacie
- `app/components`:
miesto pre vlastne feature alebo komplexne komponenty nad Nuxt UI
- `app/composables`:
zdielana klientska logika, napr. tema a logger
- `app/plugins`:
Nuxt pluginy dostupne v runtime
- `tests`:
Vitest testy pre store-y, pluginy, middleware a i18n konzistenciu
- `app/assets/styles`:
globalne SCSS styly, tokeny a tema
- `i18n/locales`:
preklady pre jednotlive jazyky
- `.vscode`:
odporucane rozsirrenia, settings a debug konfiguracia
- `nuxt.config.ts`:
hlavna konfiguracia Nuxtu, modulov, globalnych stylov a i18n
- `vitest.config.ts`:
Vitest aliasy pre `~`, `@`, `~~` a `@@`, aby sa dali testovat Nuxt subory mimo runtime
## Ako pouzit tento template
### 1. Vytvor projekt z template
Pouzi tento repozitar ako zaklad a uprav si aspon:
- nazov projektu v `package.json`
- titulok, meta a popis v `nuxt.config.ts`
- texty v `i18n/locales/sk.json` a `i18n/locales/en.json`
- uvodnu stranku v `app/pages/index.vue`
- vizualny styl v `app/assets/styles`
### 2. Nastav prostredie
Skopiruj `.env.example` do `.env` a dopln vlastne hodnoty podla potreby.
Priklady:
```bash
cp .env.example .env
```
```powershell
Copy-Item .env.example .env
```
## Spustenie projektu
### Lokalny vyvoj na hoste
Pozadovane je:
- Node.js `^22.12.0 || >=24`
- `corepack`
Spustenie:
```bash
corepack enable
pnpm install
pnpm dev
```
Potom otvor `http://localhost:3000`.
Poznamky:
- pri prvom starte moze Nuxt v dev rezime buildit pomalsie
- ak je port `3000` obsadeny, Nuxt pouzije iny port, typicky `3001`
- po otvoreni stranky sa moze prvy Vite build spustit az na prvy request
### Produkcny Docker image
Template obsahuje pripraveny:
- [Dockerfile](/c:/Data/Development/MANET/prjtemplates/vue/Dockerfile)
- [.dockerignore](/c:/Data/Development/MANET/prjtemplates/vue/.dockerignore)
Build image:
```bash
docker build -t nuxt-workspace-template:latest .
```
Spustenie kontajnera:
```bash
docker run --rm -p 3000:3000 nuxt-workspace-template:latest
```
Kontajner spusti hotovy Nitro server z `.output/server/index.mjs` a aplikacia bude dostupna na `http://localhost:3000`.
Ak potrebujes odovzdat runtime premenne:
```powershell
docker run --rm -p 3000:3000 `
-e NUXT_PUBLIC_API_BASE_URL=https://api.example.com `
-e NUXT_PUBLIC_AUTH_MODE=userinfo `
nuxt-workspace-template:latest
```
Poznamky:
- image je urceny pre release a deploy, nie pre hot-reload vyvoj
- build stage pouziva `pnpm install --frozen-lockfile` a `pnpm build`
- runtime stage pouziva hardened distroless Node 24 image a publikuje port `3000`
- runtime image neobsahuje shell ani balast navyse, co pomaha znizit attack surface
## Zakladne skripty
- `pnpm dev`: spusti vyvojovy server
- `pnpm build`: vytvori produkcny build
- `pnpm preview`: spusti preview produkcneho buildu
- `pnpm generate:api`: spusti pripraveny OpenAPI codegen workflow
- `pnpm generate:example-api`: vygeneruje ukazkoveho klienta do `openapi-client/example` cez `@hey-api/openapi-ts`
- `pnpm lint`: spusti ESLint
- `pnpm lint:fix`: opravi cast lint problemov automaticky
- `pnpm typecheck`: spusti Nuxt typecheck
- `pnpm test`: spusti Vitest v beznom rezime
- `pnpm test:run`: spusti Vitest jednorazovo
- `pnpm format`: skontroluje formatovanie cez Prettier
- `pnpm format:fix`: naformatuje subory cez Prettier
## Automaticke Overenie
Template ma pripraveny automaticky test coverage pre najdolezitejsie stavebne casti:
- store-y `auth` a `ui`
- auth plugin pre mody `disabled`, `mock` a `userinfo`
- auth middleware pre `public`, `requiresAuth` a `roles`
- API wrapper a API plugin
- logger plugin a `useLogger()`
- konzistenciu i18n klucov medzi `sk` a `en`
Odporucany minimalny verify postup pred vacsou zmenou:
```bash
pnpm lint
pnpm typecheck
pnpm test:run
pnpm build
```
Ak chces spustit len novejsie infrastrukturalne testy template-u:
```bash
pnpm vitest run tests/auth.plugin.spec.ts tests/auth.middleware.spec.ts tests/i18n.locales.spec.ts tests/api.plugin.spec.ts tests/logger.plugin.spec.ts tests/use-logger.spec.ts
```
## Ako v tomto template vyvijat
### Kde upravovat stranky
Kazdy subor v `app/pages` reprezentuje route.
Priklad:
- `app/pages/index.vue`: domovska stranka `/`
Ak chces pridat novu stranku, vytvor novy `.vue` subor v `app/pages`.
### Kde upravovat spolocny layout
Hlavny layout aplikacie je v:
- `app/layouts/default.vue`
Tu sa nachadza spolocna hlavicka, prepinac jazyka a prepinac temy. Vsetky stranky renderovane cez `NuxtPage` sa zobrazia v tomto layoute.
Layout je postaveny na Nuxt UI komponentoch, najma `UBadge` a `USelect`. Korektne obalenie aplikacie cez `UApp` je v `app/app.vue`.
### Kde upravovat preklady
Preklady su v:
- `i18n/locales/sk.json`
- `i18n/locales/en.json`
Projekt pouziva `@nuxtjs/i18n` s jazykmi:
- `sk` ako default
- `en` ako druhy jazyk
Ak pridas novy text do komponentu, dopln ho do oboch JSON suborov.
### Kde upravovat temu a vizual
Globalne styly su nacitane cez `nuxt.config.ts` z:
- `app/assets/styles/ui.css`
- `app/assets/styles/main.scss`
Subory stylov:
- `app/assets/styles/ui.css`: nacitanie Tailwind CSS a Nuxt UI vrstvy
- `app/assets/styles/_tokens.scss`: lahke app-level tokeny, napr. font, radius a layout rozmery
- `app/assets/styles/_theme.scss`: volitelne theme override-y nad Nuxt UI tokenmi
- `app/assets/styles/_base.scss`: globalne layout a app-specific styly
Theme runtime logika je v:
- Nuxt UI a `useColorMode()`
Template rozlisuje:
- preferenciu temy: `light`, `dark`, `system`
- vyslednu aktivnu temu: `light` alebo `dark`
Odporucany pristup je nemenit cely design system rucne, ale nechat Nuxt UI ako zdroj pravdy a upravovat len:
- `nuxt.config.ts` cez `appConfig.ui.colors` ako prvy krok pre semanticke farby ako `primary` a `neutral`
- `_theme.scss` pre male vizualne doladenia nad Nuxt UI tokenmi
Prakticky to znamena:
- v `ui.css` nechaj iba `@import "tailwindcss"` a `@import "@nuxt/ui"`
- v `nuxt.config.ts` zacni semantickymi farbami a inymi Nuxt nastaveniami
- v `_tokens.scss` men spolocne hodnoty ako `--ui-radius`, font alebo layout sirku
- v `_theme.scss` men light/dark rozdiely cez Nuxt UI CSS premenne
- v `_base.scss` rob app-level layout a globalne utility pre vlastne bloky ako `.shell`, `.page-grid` a podobne
### Ako funguje prepnutie temy
Runtime prepnutie temy je postavene na `useColorMode()` a prepinaci v `app/layouts/default.vue`.
Aktualna preferencia moze byt:
- `light`
- `dark`
- `system`
Pouzitie v komponente:
```ts
const colorMode = useColorMode()
colorMode.preference = 'dark'
```
Ak chces spravit vlastne tlacidlo na prepnutie temy:
```vue
<script setup lang="ts">
const colorMode = useColorMode()
function toggleTheme() {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
</script>
<template>
<UButton @click="toggleTheme">
Prepnut temu
</UButton>
</template>
```
### Ako menit vizual bez vlastneho design systemu
Najcastejsie scenare:
- chces inu primarnu farbu buttonov a aktivnych prvkov:
najprv skus `appConfig.ui.colors` v `nuxt.config.ts`
- chces jemnejsie texty, tmavsie pozadie alebo iny border v dark mode:
zmen Nuxt UI CSS premenne v `_theme.scss`
- chces iny radius alebo sirsu app shell:
zmen hodnoty v `_tokens.scss`
- chces iny layout alebo spacing vlastnych blokov:
uprav `_base.scss`
Priklad zmeny radiusu a layoutu:
```scss
:root {
--ui-radius: 1rem;
--page-max-width: 1320px;
}
```
Priklad jemneho doladenia backgroundu a borderov:
```scss
:root,
.light {
--ui-bg: #f8fafc;
--ui-bg-muted: #f1f5f9;
--ui-border: #dbe4ee;
}
.dark {
--ui-bg: #0b1220;
--ui-bg-muted: #111827;
--ui-border: #1f2937;
}
```
Priklad zmeny intenzity primarnej farby medzi light a dark modom:
```scss
:root {
--ui-primary: var(--ui-color-primary-600);
}
.dark {
--ui-primary: var(--ui-color-primary-400);
}
```
To je vhodne hlavne vtedy, ked chces nechat Nuxt UI komponenty a ich logiku bez zmeny, ale potrebujes jemne upravit kontrast alebo ton farby.
### Priklad konfiguracie v tomto template
Aktualny template drzi semanticke farby v `nuxt.config.ts`:
```ts
export default defineNuxtConfig({
appConfig: {
ui: {
colors: {
primary: 'blue',
neutral: 'slate'
}
}
}
})
```
Tento zapis hovori Nuxt UI, aku paletu ma ma preferovat pre:
- `color="primary"`
- `color="neutral"`
- utility ako `text-primary`, `bg-primary`, `text-muted`, `bg-default` a podobne
Ak by si pri konkretnej verzii Nuxt UI potreboval jemnejsiu kontrolu nad realnym vysledkom, najspolahlivejsia cesta je doplnit CSS tokeny v `_theme.scss`, napr. `--ui-primary`, `--ui-bg` alebo `--ui-border`.
### Kde upravovat komponenty
Template pouziva standardne Nuxt UI komponenty ako predvolenu UI vrstvu.
Najcastejsie pouzite v template:
- `UButton`
- `UCard`
- `UInput`
- `USelect`
- `UFormField`
- `UAlert`
- `UBadge`
Pouzitie v komponente:
```vue
<UCard variant="soft">
<template #header>
<h2>Nadpis</h2>
</template>
<UFormField label="Meno">
<UInput v-model="name" />
</UFormField>
<UButton>Ulozit</UButton>
</UCard>
```
Ak budes chciet rozsirit UI o vlastne komplexne komponenty, odporucany postup je skladat ich nad Nuxt UI, nie vytvarat paralelnu mini kniznicu zakladnych button/input/card komponentov.
### Kde upravovat logger
Logger je pripraveny ako Nuxt plugin a composable:
- `app/plugins/logger.ts`
- `app/composables/useLogger.ts`
Pouzitie v komponente:
```ts
const logger = useLogger()
logger.info('Akcia vykonana', { section: 'home' })
```
Logy z klienta idu do konzoly prehliadaca.
Logger ma aj automaticke testy, ktore overuju prefix, timestamp a spravanie s payloadom aj bez neho.
### Kde upravovat API a OpenAPI kontrakt
Zaklad API vrstvy je v:
- `app/plugins/api.client.ts`
- `app/composables/useApi.ts`
- `app/types/api.ts`
- `api/wrappers`
OpenAPI priprava je v:
- `openapi-spec`
- `openapi-client`
- `openapi-ts.config.ts`
Template funguje aj bez generovaneho klienta. Predvoleny wrapper `api/wrappers/example.ts` pouziva bezny `fetch` styl cez `$fetch`, ale ma rovnaky tvar ako vrstva, ktoru vies neskor napojit na vygenerovany OpenAPI client.
API plugin a ukazkovy wrapper maju samostatne Vitest testy, takze zmeny v `runtimeConfig` alebo wrapper rozhrani vies zachytit automaticky.
Pouzitie v stranke alebo komponente:
```ts
const api = useApi()
const health = await api.example.getHealth()
const welcome = await api.example.getWelcome()
```
Odporucany vzor:
- komponent alebo page vola `useApi()`
- `useApi()` vracia klientov injectnutych z `app/plugins/api.client.ts`
- konkretne HTTP volania alebo OpenAPI klient je schovany vo `api/wrappers`
Tymto sposobom ostane UI oddelene od detailov backend komunikacie.
Zakladne env pre API:
- `NUXT_PUBLIC_API_BASE_URL`
- `NUXT_PUBLIC_API_TIMEOUT_MS`
Zakladny generator prikaz:
```bash
pnpm generate:api
```
Odporucany postup:
1. nahrad `openapi-spec/example-api.yaml` vlastnou specifikaciou
2. uprav `openapi-ts.config.ts`
3. spusti `pnpm generate:api`
4. napoj vygenerovaneho klienta cez `api/wrappers`
Ak uz mas backend kontrakt cez OpenAPI, odporucany sposob integracie je:
1. pridaj alebo aktualizuj `.yaml` specifikaciu v `openapi-spec`
2. vygeneruj klienta do `openapi-client`
3. v `api/wrappers` vytvor tenku vrstvu, ktora premapuje volania na domenove funkcie
4. z komponentov volaj iba `useApi()`, nie vygenerovany klient priamo
Poznamka ku gitu:
- obsah `openapi-client` je v template ignorovany, pretoze ide o generovane subory
- v gite ostava len `openapi-client/README.md`, aby bolo jasne, na co adresar sluzi
- ak bude tvoj tim chciet verzovat aj generovanych klientov, uprav `.gitignore`
### Kde upravovat autorizaciu
Auth vrstva je zamerne volitelna. Ak ju projekt nepotrebuje, ostava vypnuta.
Zakladne casti su v:
- `app/plugins/auth.ts`
- `app/composables/useAuth.ts`
- `app/middleware/auth.global.ts`
- `app/stores/auth.ts`
- `app/types/auth.ts`
Rezim auth sa nastavuje cez `.env`:
- `NUXT_PUBLIC_AUTH_MODE=disabled`: auth je vypnuta a middleware nic nevynucuje
- `NUXT_PUBLIC_AUTH_MODE=mock`: lokalny vyvoj s mock userom
- `NUXT_PUBLIC_AUTH_MODE=userinfo`: nacitanie usera z endpointu `NUXT_PUBLIC_AUTH_USERINFO_URL`
Pouzitie v komponente:
```ts
const auth = useAuth()
await auth.ensureInitialized()
if (auth.isAuthenticated.value) {
console.log(auth.user.value?.email)
}
```
Pouzitie cez store:
```ts
const authStore = useAuthStore()
if (authStore.hasRole('ADMIN')) {
// zobraz admin cast rozhrania
}
```
Ak chces ochranit konkretnu stranku, pouzi route meta:
```ts
definePageMeta({
requiresAuth: true
})
```
Alebo s rolami:
```ts
definePageMeta({
requiresAuth: true,
roles: ['ADMIN']
})
```
Bezny scenar:
- pocas lokalneho vyvoja nastav `NUXT_PUBLIC_AUTH_MODE=mock`
- pre projekt bez prihlasenia nechaj `NUXT_PUBLIC_AUTH_MODE=disabled`
- pre realne SSO alebo proxy endpoint pouzi `NUXT_PUBLIC_AUTH_MODE=userinfo`
Auth middleware sa spusta globalne, ale zasahuje len na routach s `requiresAuth` alebo `roles`.
### Kde upravovat globalny stav cez Pinia
Pinia sa hodi na stav, ktory je zdielany vo viacerych castiach aplikacie.
Pripravene store-y:
- `app/stores/auth.ts`: user, role, session stav
- `app/stores/ui.ts`: loading a notifikacie
Pouzitie `ui` store:
```ts
const uiStore = useUiStore()
uiStore.startLoading()
try {
uiStore.pushNotification({
title: 'Ulozene',
message: 'Zmena bola uspesne ulozena.',
tone: 'success'
})
} finally {
uiStore.stopLoading()
}
```
Pouzitie `auth` store:
```ts
const authStore = useAuthStore()
const userName = authStore.displayName
const isLoggedIn = authStore.isAuthenticated
```
Odporucanie:
- lokalny stav formulára nechaj v komponente
- zdielany stav typu user, loading, notifikacie alebo filtre dava zmysel drzat v store
### Ako pouzit Nuxt UI v tomto template
Nuxt UI je zapojene ako Nuxt modul a je predvolenou UI vrstvou template.
Zakladne pouzitie:
1. do page alebo komponentu pouzi `U*` komponenty priamo
2. nebuduj dalsiu vrstvu `BaseButton`, `BaseInput`, `BaseCard`, ak na to nie je silny dovod
3. vlastne komplikovane komponenty, napriklad diagramy alebo specialne editory, stavaj ako bezne Vue komponenty a Nuxt UI pouzi na ich okolie, toolbar, formulare a akcie
Priklad:
```vue
<template>
<UCard>
<template #header>
<div class="stack">
<p class="section-kicker">Demo</p>
<h2>Nuxt UI komponent</h2>
</div>
</template>
<UAlert
color="info"
variant="soft"
title="Stav"
description="Komponent je pripraveny."
/>
</UCard>
</template>
```
### Kde upravovat hlavnu konfiguraciu
Hlavne nastavenia su v:
- `nuxt.config.ts`
Tu upravis napr.:
- globalne CSS
- Nuxt moduly
- title a meta tagy
- i18n konfiguraciu
- devtools spravanie
## Odporucany workflow
Pri beznej praci sa osvedci tento postup:
1. Spusti `pnpm dev`.
2. Otvor aplikaciu v prehliadaci.
3. Men stranky v `app/pages`, layout v `app/layouts` a texty v `i18n/locales`.
4. Priebežne kontroluj typy a lint:
```bash
pnpm typecheck
pnpm lint
```
5. Pred odovzdanim alebo commitom over:
```bash
pnpm format
pnpm test:run
pnpm build
```
## VS Code
Repozitar obsahuje:
- `.vscode/settings.json`: workspace nastavenia
- `.vscode/extensions.json`: odporucane rozsirrenia
- `.vscode/launch.json`: jednoduche spustenie `pnpm dev` z VS Code
Predinstalovane a odporucane rozsirrenia su zamerane najma na:
- Vue a TypeScript
- ESLint a Prettier
- i18n preklady
- Vitest
## Poznamky k dev rezimu
- `pnpm install` spusta `postinstall`, ktory vola `nuxt prepare`
- OpenAPI codegen ide cez `@hey-api/openapi-ts`, takze netreba Javu
- prvy start po cistom install moze byt pomalsi
- prvy Vite build sa moze spustit az pri prvom otvoreni stranky
- ak sa objavi problem s viacerymi servermi, ukonci beziace Node alebo Nuxt procesy vo svojom terminali alebo cez Spravcu uloh a spusti iba jeden `pnpm dev`
## Co typicky zmenit ako prve
Po vytvoreni noveho projektu z template sa obvykle meni:
- branding a texty v prekladoch
- titulky a meta udaje
- farby, spacing a tokeny v stylech
- obsah `app/pages/index.vue`
- pouzitie a konfiguracia Nuxt UI komponentov podla potrieb projektu
- vlastne feature komponenty v `app/components`
- doplnenie dalsich stranok, API endpointov a testov