13. modulModul-ökoszisztéma Workers-szűrővel
Nuxt for Devs · 13. modul

Modul-ökoszisztéma — Workers-szűrővel

A Nuxt legnagyobb kényelmi előnye a modulrendszer: egy sor a konfigban, és kész a képoptimalizálás vagy az i18n. Csakhogy a modulok nem egyformán viselkednek edge-runtime alatt. Ez a modul nem katalógus, hanem szűrő: négy kérdés, amivel bármelyik modulról eldöntöd, hogy megy-e — plusz egy megrostált lista arról, amit ténylegesen érdemes használni.

13.1Mi az a Nuxt-modul valójában?

Nem sima npm-függőség, hanem build-időben lefutó kód, ami módosítja a projektedet: hozzáad fájlokat a virtuális fájlrendszerhez, regisztrál komponenseket és composable-öket, felvesz server route-okat, átírja a Vite- vagy a Nitro-konfigot.

Ebből három gyakorlati következmény adódik:

13.2A négy kérdés — a szűrő

Mielőtt beveszel egy modult, fusd át ezt a négyet. Öt perc, és megspórolja a „deploy után 500-as” estét:

#KérdésHogyan derül ki
1 Fut-e futásidőben a szerveren? Ha csak build-time (pl. ikon-generálás, CSS), akkor Workers-en nem érdekes. Van-e runtime/server/ könyvtára a modulnak; ad-e hozzá server handlert.
2 Van-e natív függősége? A natív addon soha nem fut a workerd-ben. npm ls sharp canvas bcrypt better-sqlite3 — vagy nézd meg a modul dependencies-ét.
3 Használ-e fájlrendszert futásidőben? Nincs fs. A modul dokumentációja említ-e cache-könyvtárat, .cache/-t, feltöltési mappát.
4 Mekkora a bundle-hatása? Van méretlimit (15. modul). Mérd: wrangler check startup a modul előtt és után (11.3).
Az ötödik, íratlan kérdés: karbantartott-e? Az 1. modulban ez szerepelt a „mit veszítesz” listán: egy elhagyott modul a következő Nuxt-major frissítésnél lesz a te problémád. Nézd meg az utolsó kiadás dátumát és azt, hogy támogatja-e már a Nuxt 4-et — nem azért, mert a régi rossz, hanem mert a frissítési útad rajta múlik.

13.3A megrostált lista

Amit szinte biztosan használni fogsz

ModulMireWorkers-en
nuxt-auth-utilsSession, OAuth, jelszó-helperek (10. modul)Megy
@vueuse/nuxtTöbb száz apró composable, SSR-tudatosanMegy — tisztán kliens/izomorf
@nuxt/fontsWebfont-kezelés, self-hosting, layout-ugrás nélkülBuild-idejű, nincs futásidejű kockázat
@nuxt/imageKépoptimalizálás — de nem az alapértelmezett providerrelLásd a 13.4-et
@nuxtjs/i18nTöbb nyelv, path-prefix, lokalizált route-okMegy — a fordítások a bundle-ben
@nuxt/test-utilsKomponens- és e2e-teszt (16. modul)Dev-only
nitro-cloudflare-devBindingok lokálisan (18. modul)Dev-only

Amit érdemes megfontolni

ModulMireMérlegelés
@pinia/nuxtStore-kezelésCsak ha tényleg összetett a domain-logika — a useState sokáig elég (6. modul)
@nuxt/uiKész komponenskönyvtár TailwinddelSok kódot spórol, de a stílusod hozzáköti. Alternatíva: sima Tailwind + néhány saját komponens
@nuxtjs/seo (sitemap, robots, schema)SEO-eszközök egy csomagbanHasznos, de nézd meg, mennyi fut belőle futásidőben (a sitemap-generálás igen). A 20. modulban részletesen
@nuxt/scriptsHarmadik fél scriptek (analitika, chat) betöltés-optimalizálvaJó, ha sok külső scriptet töltesz — egyébben túlzás
@vite-pwa/nuxtPWA, service worker, offlineHa az appod „app-szerű”. Óvatosan az SSR-rel: a service worker cache-e és az SSR-payload együtt meglepetéseket okoz
@nuxt/contentMarkdown-alapú tartalom (blog, doksi)v3-ban Workers-en is megy, D1-gyel — lásd a 13.5-öt

Amivel vigyázz

13.4@nuxt/image — a leggyakoribb Workers-buktató

Ez a modul kerül elő először, és itt esik szét először a „csak telepítem és megy” érzés.

Az @nuxt/image alapértelmezett providere (IPX) a szerveren dolgozza fel a képet — átméretez, formátumot vált, tömörít. Ehhez a sharp könyvtárat használja, ami natív addon. Workers-en ez nem opció, és nem is lesz az.

A jó hír: nem is kell, mert a Cloudflare ezt a réteget amúgy is adja. Két provider van:

cloudflare providercloudflareImages provider
Mit használImage Transformations a zónádon (/cdn-cgi/image/…)Cloudflare Images (feltöltött, kezelt képek)
A kép honnan jönBármilyen URL-ről, amit te szolgálsz ki (pl. R2, saját domain)A Cloudflare Images tárolójából
Mikor jóA képeid már nálad vannak (R2, statikus assetek)Felhasználó tölt fel képeket, és kell hozzá tárolás + variánsok
ElőfeltételImage Transformations bekapcsolva a zónánCloudflare Images előfizetés
// nuxt.config.ts — a zóna-alapú út
export default defineNuxtConfig({
  modules: ['@nuxt/image'],

  image: {
    provider: 'cloudflare',
    cloudflare: {
      baseURL: 'https://app.pelda.hu',   // a zónád — a /cdn-cgi/image/ automatikusan kerül elé
    },
    // a szokásos méret-készlet, hogy ne kelljen minden <NuxtImg>-nél megadni
    screens: { sm: 640, md: 768, lg: 1024, xl: 1280 },
  },
})
<template>
  <NuxtImg
    src="/uploads/acme/borito.jpg"
    width="960" height="540"
    sizes="sm:100vw md:50vw lg:960px"
    format="webp"
    loading="lazy"
  />
</template>
Miért jobb ez, mint a sharp? Mert a transzformáció nem a te Workeredben fut, hanem a Cloudflare hálózatán, és a végeredmény cache-elődik az edge-en. Nem fogyaszt CPU-időt, nem terheli a memórialimitet, és a második kérésnél már meg sem történik. A képfeldolgozás pont az a feladat, amit nem a kérés-útvonalon akarsz elvégezni — itt ezt nem is te végzed.
Amit lokálisan tesztelni kell. A /cdn-cgi/image/ út csak a Cloudflare-hálózaton létezik — nuxt dev alatt nincs. Fejlesztés közben ezért érdemes provider nélkül (vagy provider: 'none'-nal) dolgozni, és a képes megjelenést preview-deployon ellenőrizni. Ez a 2. modul dev-vs-prod különbségének egy konkrét esete.

13.5@nuxt/content — megy, de tudni kell, hogyan

A Content v3 lecserélte a régi, fájlrendszer-alapú modellt egy SQL-alapúra, és ezzel serverless környezetben is működik: a tartalom build-időben adatbázisba kerül, futásidőben pedig onnan olvassa. Cloudflare-en ez D1.

Két dolgot érdemes tudni róla, mielőtt beveszed:

Az alternatíva, ami sokszor jobb: ha csak néhány tucat statikus oldalról van szó (marketing, súgó), akkor a 7. modul prerender: true szabálya egyszerűbb és olcsóbb — sima .vue oldalak, build-időben statikussá téve, nulla futásidejű költséggel. A Content akkor éri meg, ha a tartalom mennyisége vagy a szerkesztési folyamat (Markdown, nem-fejlesztő szerzők) indokolja.

13.6Saját modul — mikor éri meg

Akkor, ha ugyanazt a setupot harmadszor másolod be egy projektbe, vagy ha több appod osztozik egy konvención. Egy modul váza meglepően rövid:

// modules/tenant-context.ts — a projekt gyökerében lévő modules/ automatikusan betöltődik
import { defineNuxtModule, addServerHandler, addImports, createResolver } from '@nuxt/kit'

export default defineNuxtModule({
  meta: { name: 'tenant-context', configKey: 'tenantContext' },
  defaults: { headerName: 'x-tenant' },

  setup(options, nuxt) {
    const { resolve } = createResolver(import.meta.url)

    // ① szerver middleware regisztrálása (4. modul)
    addServerHandler({
      middleware: true,
      handler: resolve('./runtime/server/tenant'),
    })

    // ② composable auto-importtal
    addImports({ name: 'useTenant', from: resolve('./runtime/composables/useTenant') })

    // ③ konfiguráció átadása a futásidőnek
    nuxt.options.runtimeConfig.public.tenantHeader = options.headerName
  },
})
Kit-segédfüggvényMire
addServerHandlerServer route vagy middleware regisztrálása
addImportsComposable auto-importba tétele
addComponentKomponens elérhetővé tétele
addPluginApp-plugin regisztrálása
extendPagesRoute-ok hozzáadása vagy módosítása
addTemplateGenerált fájl a .nuxt/-ba (pl. típusok)
Modul vagy layer? A kettő átfed, de más a súlypontjuk. A modul viselkedést ad hozzá (middleware, composable, konfiguráció) — kódban, programozottan. A layer egész fájlkészletet oszt meg (oldalak, komponensek, layoutok), amit a másik projekt felül tud írni. Ha megosztható oldalakról vagy arculatról van szó, a layer a jobb eszköz — erről szól a következő, 14. modul.

13.7Modul-higiénia

Mi jön ezután? A 14. modul a Nuxt layers-ről szól — arról a képességről, ami a te esetedben kifejezetten releváns: tenant- vagy márkaspecifikus rétegek egy közös alap fölött, külön kódbázis nélkül. Ez az, amit a Vue SPA + Express felállásban házilag kellene megírni.

13.8Ellenőrizd magad

  1. Miért nem sima npm-függőség egy Nuxt-modul?
    Válasz

    Mert build-időben lefutó kód, ami módosítja a projektet: fájlokat ad a virtuális fájlrendszerhez, komponenseket és composable-öket regisztrál, server route-okat vesz fel, átírja a Vite/Nitro konfigot. Ezért számít a sorrendjük, és ezért lehet egy modul teljesen ártalmatlan Workers-en (ha csak build-idejű) vagy kockázatos (ha futásidejű kódot is hoz).

  2. Négy kérdés, amit egy modulról fel kell tenni Workers előtt. Melyek?
    Válasz

    ① Fut-e futásidőben a szerveren, vagy csak build-time? ② Van-e natív függősége (sharp, canvas, better-sqlite3)? ③ Ír-e a fájlrendszerre futásidőben? ④ Mekkora a bundle- és hidegindítás-hatása? Plusz az ötödik, íratlan: karbantartott-e, támogatja-e a jelenlegi Nuxt-majort.

  3. Miért nem működik az @nuxt/image alapértelmezés szerint, és mi a megoldás?
    Válasz

    Mert az alapértelmezett IPX provider a szerveren dolgozza fel a képet a sharp natív könyvtárral, ami nem fut a workerd-ben. Megoldás: a cloudflare provider (Image Transformations a zónán, /cdn-cgi/image/) vagy a cloudflareImages provider. Így a transzformáció a Cloudflare hálózatán történik, cache-elve, a te CPU-időd nélkül.

  4. Mit kell tudni a @nuxt/content v3-ról Workers-en?
    Válasz

    Hogy működik — a v3 SQL-alapú, és Cloudflare-en D1-et használ. Két dolgot mérlegelj: kell hozzá egy D1-adatbázis és a tartalom-frissítés deployhoz kötött; illetve a kliensoldali navigációhoz WASM SQLite töltődik a böngészőbe, ami méretben számít. Kevés statikus oldalnál a prerender: true egyszerűbb és olcsóbb.

  5. Mikor írj saját modult, és mikor válassz layert helyette?
    Válasz

    Modult akkor, ha viselkedést osztanál meg programozottan: middleware, composable, konfigurációs konvenció — jellemzően ha harmadszor másolod ugyanazt a setupot. Layert akkor, ha fájlkészletet: oldalakat, komponenseket, layoutokat, arculatot, amit a másik projekt felül tud írni. Utóbbi a 14. modul témája.

  6. Egy modul frissítése után minden fordul lokálisan, de a preview-deploy elszáll. Hol keresd az okot?
    Válasz

    A modul futásidejű részében: valószínűleg olyan Node-API-ra vagy natív függőségre támaszkodik, ami nuxt dev alatt (Node-ban) elérhető, a workerd-ben nem. Ezért kell minden modul-frissítést preview-deployon ellenőrizni — ez az egyetlen hely, ahol valódi Workers-runtime alatt fut a kód.

Előző12. modul — Konfiguráció és a négy szint Következő 14. modul — Layers és white-label