meeko build
Comprueba el proyecto y escribe en .meeko/output/<adaptador>/ la salida de producción, con el cliente, el servidor y las páginas prerenderizadas.
meeko build construye la aplicación para producción. Primero hace todo lo que hace meeko check (y se detiene con sus mismos errores); después compila el cliente con Vite, el servidor de su adaptador y las páginas render: "prerender", y escribe una carpeta que se ejecuta sin las fuentes de la aplicación: .meeko/output/node/, bun/, deno/, cloudflare/ o static/.
El adaptador sale de --adapter, de server.adapter en meeko.config.ts o, por defecto, node.
Uso#
meeko buildC:\proyectos\tienda\.meeko\output\nodeLa única línea de la salida estándar es la carpeta generada, así que un script puede usarla (out=$(meeko build)). Los avisos van a la salida de errores.
Tipo#
meeko build [directorio] [--adapter <node|cloudflare|deno|bun|static>]Opciones#
| Opción | Tipo | Por defecto | Descripción |
|---|---|---|---|
[directorio] |
ruta | . |
Raíz del proyecto. |
--adapter <nombre> o --adapter=<nombre> |
node | bun | deno | cloudflare | static |
server.adapter, o node |
Adaptador de esta ejecución. Puede ir en cualquier posición después de build. No cambia qué opciones de server se leen: host y port sólo con server.adapter: "node", headerFiles sólo con "static", y contentSecurityPolicy y headers de un server que no es "static" se aplican con cualquier adaptador con servidor. |
MEEKO_PUBLIC_ORIGIN |
origen | ninguno | Origen de las URL absolutas (sitemap.xml, robots.txt, document.seo) si meeko.config.ts no declara site. |
.env del proyecto |
Se lee antes de la configuración, como en meeko check. |
Resultado#
| Adaptador | Carpeta | Contenido | Se ejecuta con |
|---|---|---|---|
node |
.meeko/output/node/ |
index.mjs, chunks/, client/, prerender/ |
meeko start, meeko preview o node .meeko/output/node/index.mjs; necesita node_modules con @meekojs/meeko |
bun |
.meeko/output/bun/ |
index.js con todas las dependencias, chunks/, client/, prerender/ |
bun .meeko/output/bun/index.js |
deno |
.meeko/output/deno/ |
main.js con todas las dependencias, chunks/, client/, prerender/ |
deno run --allow-net --allow-env --allow-read=.meeko/output/deno …/main.js |
cloudflare |
.meeko/output/cloudflare/ |
worker.js, wrangler.jsonc, los assets y las páginas prerenderizadas |
wrangler deploy --config .meeko/output/cloudflare/wrangler.jsonc |
static |
.meeko/output/static/ |
El HTML y el payload de cada página, los assets, 404.html y los archivos de cabeceras |
Cualquier hosting estático |
Además:
- El build de Node fija en el bundle
server.hostyserver.port(siserver.adapteres"node"), el manifiesto de rutas, endpoints y assets, y unbuildIdnuevo en cada ejecución, que desde1.7forma parte delETagde la caché de páginas. - Desde
1.7, conadapter: "node","bun","deno"o"cloudflare",server.contentSecurityPolicyyserver.headersquedan en el manifiesto de la aplicación, que los aplica a cada respuesta: la política con los hashes de cada página prerenderizada, un nonce por respuesta en SSR ydefault-src 'none'en el JSON. - El prerender usa un servidor de Node: el del propio build con
node, o uno intermedio en.meeko/build/node/con los demás adaptadores (y connodecuando haysitemap). Desde1.7, ese mismo servidor evalúasitemapEntries. sitemap.xmlyrobots.txtse escriben en el cliente si están activados.- Los módulos reciben los hooks
build:before,routes:resolvedybuild:done.
Ejemplos#
Node, con su CSP y sus cabeceras#
// meeko.config.ts
import { defineMeekoConfig } from "@meekojs/meeko/framework";
export default defineMeekoConfig({
server: {
adapter: "node",
port: 8080,
contentSecurityPolicy: { "default-src": ["'self'"], "object-src": ["'none'"], "base-uri": ["'none'"] },
headers: { "X-Content-Type-Options": "nosniff", "/admin/*": { "X-Robots-Tag": "noindex" } },
},
});meeko build && meeko startUna página prerenderizada responde entonces con content-security-policy: default-src 'self'; object-src 'none'; base-uri 'none'; style-src 'self' 'sha256-…' y x-content-type-options: nosniff. Antes de 1.7, estas dos opciones sólo existían con adapter: "static".
Otro adaptador sin tocar la configuración#
meeko build --adapter deno
meeko preview --adapter denopreview necesita el mismo --adapter: sin él, busca el build del adaptador de la configuración.
Un sitio estático con sitemap#
MEEKO_PUBLIC_ORIGIN=https://example.com meeko build --adapter static[meeko] Sin app/error.meeko, el adaptador static no genera 404.html; el hosting mostrará su propia página 404.
C:\proyectos\blog\.meeko\output\staticTodas las páginas deben ser render: "prerender" y la aplicación no puede tener API, RPC, Socket ni middleware de servidor.
En CI, con la salida en una variable#
set -e
out=$(npx meeko build)
tar -czf app.tgz -C "$out" .En PowerShell: $out = npx meeko build.
Errores comunes#
Un adaptador que no existe, o sin nombre#
meeko build --adapter vercel
meeko build --adapterAdaptador desconocido: vercel; usa node, cloudflare, deno, bun o static y Falta el nombre del adaptador en --adapter de build, ambos con código 1. Repetir la opción da --adapter aparece más de una vez en build.
meeko build --adapter nodeUn sitemap sin origen público#
// meeko.config.ts
import { defineMeekoConfig } from "@meekojs/meeko/framework";
export default defineMeekoConfig({ sitemap: true });meeko build se detiene antes de compilar nada: sitemap necesita la URL pública del sitio: declara site en meeko.config.ts (site: "https://example.com") o define MEEKO_PUBLIC_ORIGIN al construir. document.seo con canonical u ogUrl da el mismo error.
// meeko.config.ts
import { defineMeekoConfig } from "@meekojs/meeko/framework";
export default defineMeekoConfig({ site: "https://example.com", sitemap: true });El adaptador static con partes de servidor#
# la aplicación tiene server/api/health.get.ts
meeko build --adapter staticEl adaptador static genera un sitio sin servidor, pero la aplicación necesita uno:
- endpoints de API: GET /api/health (server/api/health.get.ts)
Usa render: "prerender" (con prerenderEntries en las rutas dinámicas) y quita lo que se ejecuta en el servidor, o elige otro adaptador.meeko build --adapter nodeUna ruta dinámica prerenderizada sin prerenderEntries#
// app/pages/blog/[slug].route.ts
import { definePage } from "@meekojs/meeko/framework";
export const route = definePage({ render: "prerender" });meeko check no lo detecta; meeko build falla al prerenderizar con Dynamic prerender route /blog/[slug] requires prerenderEntries.
// app/pages/blog/[slug].route.ts
import { definePage } from "@meekojs/meeko/framework";
export const route = definePage({ render: "prerender", prerenderEntries: [{ slug: "hola-meeko" }] });Un archivo de public/ que choca con uno generado#
public/sitemap.xml ← y sitemap: true en meeko.config.tsEl archivo público sitemap.xml (de public/ o de un módulo) choca con el que genera la opción sitemap de meeko.config.ts; quita uno de los dos. Lo mismo vale para robots.txt, y con Cloudflare, public/_meeko está reservado.
public/favicon.svg ← sitemap.xml lo genera el buildNotas#
- Comprueba antes de construir.
meeko buildejecuta la comprobación completa demeeko check(TypeScript incluido), así que en CI basta conmeeko buildsi no necesitas separar las fases. Un error de tipos detiene el build sin escribir la salida. - La salida es autónoma. Los builds no leen
app/,server/nimeeko.config.tsal ejecutarse, ni cargan TypeScript o Vite. El de Node necesitanode_modules(con@meekojs/meeko); los de Bun y Deno no. - Variables de entorno.
MEEKO_HOST,MEEKO_PORT(oPORT) yMEEKO_PUBLIC_ORIGINse leen al arrancar la salida, no al construir; el build sólo fija los valores por defecto deserver.hostyserver.port. Lo que leeprocess.envdurante el build es lo que usan el prerender ysitemapEntries. - Sesiones. Construir no exige sesiones persistentes, pero arrancar la salida en producción sí: define
MEEKO_REDIS_URLo declarasessionsenserver/runtime.ts(véasemeeko start). - Rendimiento. El build de cliente y el de servidor son dos pasadas de Vite; con
sitemapyadapter: "node"el servidor se construye dos veces. La comprobación con TypeScript suele ser la parte más larga. - Windows y POSIX. La ruta impresa usa el separador del sistema.
.meeko/output/<adaptador>/se vacía en cada build: no guardes nada ahí.