Vinext 1.0 全栈落地技能(v3.0.0)
输入输出契约:输入 = 两类之一——① 一个 Next.js 16 项目目录 + 目标平台(cloudflare / node / nitro);② 一个从零开始的全栈项目想法(NestJS + 现代前端)。输出 = 可本地运行的生产构建(build + start 冒烟通过)+ 可选部署 URL + 一份部署摘要。任何一步失败都要给出可执行修复,不要把原始堆栈直接丢给用户。
双主线定位(v3.0.0 起):本技能覆盖两条独立主线——迁移线(Next.js 16 → vinext,下方阶段 1-5)与从 0 开发线(NestJS + 现代前端,见「路径 D」)。两条线共用同一套验证/沉淀纪律,互不依赖:只迁移不走开发线,只开发不走迁移线,都成立。
Vinext 在 Vite 8 上重新实现 Next.js 16 的公开 API 层(非 fork 非包装器)。既有 app/、pages/、next.config.js 原样不动。兼容性三口径别混用(2026-10-14 复核):① 官方 1.0 GA 公告口径:每晚跑 Next.js 官方 e2e 套件,test compatibility >99%,不含 cache components;② 官网 API surface 口径:覆盖 94% 的 Next.js 16 API;③ 兼容性仪表盘快照:supported pass rate 每日浮动(2026-09-30 快照 99.7%,基线 Next.js v16.2.6 / 799 测试文件)。对用户报数用 ①,逐项核对用 ③,口径关系见 references/compatibility.md §1。
> 本技能所有命令与参数均经 vinext 1.0 GA 系列本地实测核验(当前 latest 1.1.0,npm engines node >=22;1.0.0 于 2026-09-28 GA 毕业,1.0.1/1.1.0 为后续修复版)。标注【实测】 的为真实踩坑沉淀,沉淀规则见「沉淀闭环」。版本边界:beta 系列(≤1.0.0-beta.13)的旧结论已按 GA 后行为修订,涉及处均标注版本。
环境预检(先做这个)
- Node.js 版本分两层看:vinext 包本身 npm engines 只要求
>=22;但 Cloudflare 部署路径(@cloudflare/config/ Cloudflare Vite plugin v2)硬门槛>= 22.18.0——低于此版本加载即报错——【实测】Node 22.13.1 执行vite build直接失败:Error: cloudflare.config.ts loading requires Node.js v22.18.0 or higher。不足时升级:nvm install 22 && nvm alias default 22(迁移存量项目 Node ≥ 20.19)。纯 Node/Nitro 路径按 engines>=22执行即可,但建议统一 ≥22.18.0 免踩坑。 - 一键探测:
python3 scripts/detect_env.py <项目目录>自动输出 Node 精确版本、包管理器、是否 Next.js 项目、已配置平台、是否已有 vite 配置,并给出路径建议——零输入感知,别让用户手动贴环境。 - 包管理器:看 lockfile ——
pnpm-lock.yaml→pnpm /yarn.lock→yarn /bun.lock*→bun / 其余→npm。 - 是否 Next.js 项目:
package.json里有next。迁移路径没有则 STOP。 - 路由类型:根或
src/下有app/→ App Router;只有pages/→ Pages Router;可共存。
报错定位协议(任何阶段遇错,查沉淀前必做):学自 ima RAG 的 Query 改写——模糊提问检索必跑偏。流程:① 从报错里提取精确错误串(如 requires Node.js v22.18.0 or higher,原样复制,不改写不概括);② 拿精确串 + 场景词(如"Vinext 构建")查 references/troubleshooting.md 和 references/learnings.md;③ 多条命中时先按场景匹配度、再按时间排序;④ 未命中再动手排查,排查结论按格式回填 learnings。禁止拿"构建报错""部署失败"这类模糊词直接搜经验库。
路由判断(先做这个)
| 用户意图 | 走哪条路径 |
|---|---|
| 从零新建 Vinext 项目 | 路径 A:官方脚手架(最快) |
| 已有 Next.js 项目要迁 | 路径 B:迁移流水线(主流) |
| 有 Vinext DevKit 套件(v1.1.0)可 fork | 路径 C:套件起步(客户项目/模板复用) |
| 要从 0 开发全栈项目(NestJS + 现代前端) | 路径 D:从 0 开发(操作手册见专章 + references/fullstack-nestjs.md) |
| 项目已就绪,要部署 | 阶段 4:部署 |
| 要把经验/交付物沉淀进 ima 知识库 | 参考 references/ima-integration.md |
与官方 Agent Skill 的分工(2026-10-14 复核,别混用):Cloudflare 官方自己也发布了 vinext Agent Skill(npx skills add cloudflare/vinext,对工具说 "migrate this project to vinext")——它只管迁移单点(check → init → 生成配置)。本技能是全栈落地:迁移 → 部署 → 缓存/绑定 → 本地验证 → 部署摘要 → 沉淀闭环,且全部经中文语境实测坑库校准。用法:迁移引导可借官方 skill 的思路,但命令参数、平台判断、坑位规避、沉淀回收以本技能为准;用户同时装了两个时,主动说明分工避免困惑。
从 0 开发全栈项目(路径 D:NestJS + 现代前端)
适用:用户要从零做一个全栈项目(后端 API + 前端页面),且未指定技术栈。默认栈(2026-10-15 实证可跑):NestJS 12(ESM)+ TypeORM 0.3 + better-sqlite3(开发)/ MySQL 8(生产)+ Redis + BullMQ(队列)+ Vite + React 19 前端 + PM2 / Docker 部署。用户指定了其他栈时按其指定执行,本章的工程纪律(显式列类型、四件套、迁移先行、冒烟口径)仍然适用。
操作手册:完整步骤见 references/fullstack-nestjs.md(S1 需求澄清 → S2 选型 → S3 脚手架 → S4 数据模型 → S5 API 四件套 → S6 前端联调 → S7 部署验收)。本章只列每阶段必须做到的硬性口径:
| 阶段 | 必须做到 | 不做到会怎样(实测坑) |
|---|---|---|
| S1 需求澄清 | 九问清单过一遍:用户角色/核心实体/权限/并发量/文件存储/第三方/部署环境/预算/时间线 | 需求漂移,返工 |
| S3 脚手架 | nest new 后确认 package.json 带 "type": "module",tsconfig 为 nodenext,import 一律带 .js 后缀 |
混入 CJS 写法启动即崩 |
| S4 数据模型 | entity 每个 @Column 显式写 type;TypeOrmModule.forRoot 的 entities 显式数组列举(禁止 __dirname glob 字符串);迁移用 tsx 跑 typeorm CLI |
glob 写法在 ESM 下报 ERR_AMBIGUOUS_MODULE_SYNTAX;缺 type 时 migration:generate 报 Column type for X#y is not defined |
| S5 API 四件套 | ValidationPipe(whitelist + transform + forbidNonWhitelisted)+ ResponseInterceptor(统一 {code:0,data,message})+ AllExceptionsFilter + Swagger |
响应结构每次手写,前后端契约漂移 |
| S6 前端联调 | Vite 配置 proxy 指向 http://localhost:3000(Nest 默认端口),CORS 用 origin:true |
跨域假故障 |
| S7 部署验收 | PM2(pm2 start dist/main.js --name api)或 Dockerfile 多段构建;上线前 npm run build && npm run start 本地冒烟 + 迁移 migration:run |
直接 synchronize:true 上生产,Schema 失控 |
硬性纪律:① 迁移先行——生产环境 synchronize 必须为 false,Schema 变更一律走 migration:generate + migration:run;② 每阶段结束本地冒烟(build 通过 + start 后 curl 探活);③ 新踩的坑按「沉淀闭环」回填 references/learnings.md。
速查表(双列:CLI 原生命令 vs 脚手架 npm script)
新建项目由 create-vinext-app 生成,package.json 的 script 与 CLI 原生命令名字不同,别照抄失效:
| 目的 | CLI 原生命令 | 脚手架生成的 npm script |
|---|---|---|
| 新建项目 | pnpm create vinext-app@latest my-app(官方 README 示例;npm create 等价) |
—— |
| 兼容性扫描 | npx vinext check |
npm run check(若生成) |
| dev server | vite dev / vinext dev(官方首选 vite dev) |
npm run dev |
| 生产构建 | vinext build / vite build(官方 benchmark:33-route App Router 应用 vs Next.js 16.1.6 Turbopack 7.38s,vinext Rollup 4.64s≈1.6x、Rolldown 1.67s≈4.4x;官网保守标 up to 2×,client bundle 小 56-57%。CI 环境数据,仅方向性参考) |
npm run build |
| 本地生产服务器 | vinext start / vite preview |
npm run start |
| 部署 Workers | npx @vinext/cloudflare deploy |
npm run deploy(= vinext-cloudflare deploy) |
| lint | vinext lint(委托 eslint 或 oxlint,推荐 oxlint) |
npm run lint |
| 类型生成 | vinext typegen |
npm run typegen |
阶段 1:兼容性扫描
npx vinext check
- 看评分报告;critical 项先告知用户再继续
- 1.0 起 check 会额外报告
next.config里被 vinext 忽略或采纳的选项(release #3508)——逐条念给用户,别只报总分 - 参考在线仪表盘 https://vinext.dev/compatibility(每晚更新)与
references/compatibility.md - 已知基准:官网 API surface 口径 94%(2026-10-14 复核);逐项明细以仪表盘当日快照为准
阶段 2:自动迁移 vinext init(非破坏式)
自动做:跑 check → 装依赖 → 加 "type": "module" → CJS 配置改名 .cjs → 加 *:vinext 脚本 → 生成 vite.config.ts → 选平台时生成 cloudflare.config.ts(Cloudflare 时装 cf + Vite plugin v2)。还自动修复:tsconfig 路径别名、MDX 检测、native 模块(sharp/resvg/satori/lightningcss/@napi-rs/canvas)自动 stub。
全部选项(实测 --help):
npx vinext init \
--platform=cloudflare \ # 必传给 agent 调用:cloudflare 或 node(跳过交互)
--port 3001 \ # 迁移后 dev 端口(避开 Next 的 3000,双轨并存)
--cdn-cache response-store \ # none|response-store|workers-cache|static-assets|data-cache;官方默认推荐 response-store
--response-store-mode service-binding \ # 或 self-contained
--data-cache kv \ # kv 或 none(⚠️ 见下方警告)
--image-optimization cloudflare-images \ # 或 none
--warm-cache \ # 给 deploy 脚本加缓存预热
--prerender \ # 构建期预渲染静态路由
--no-install \ # 只写依赖清单不安装
--force # 覆盖已有 Vite 配置
> KV data cache 绑定声明(版本边界,2026-10-14 复核):create-vinext-app / vinext init 传 --data-cache=kv,beta 系列实测生成的 cloudflare.config.ts 里只有 ASSETS / IMAGES,没有 VINEXT_KV_CACHE。1.0.0 起官方已支持 KV namespace autoprovisioning(release #3528)并移除了手动 provisioning 步骤(#3529)——但自动开通的是 namespace,cloudflare.config.ts 的 binding 声明与 kvDataAdapter({ binding: "VINEXT_KV_CACHE" }) 的显式对应关系仍要人工核对(本地缺绑定时优雅降级不报错,部署后不生效也不报警,是最容易静默翻车的一项)。核对不过时手动补:
> bash
> wrangler kv namespace create VINEXT_KV_CACHE # 记下返回的 namespace id
>
> 然后把该 KV binding 显式写进 cloudflare.config.ts 的 env,与 kvDataAdapter({ binding: "VINEXT_KV_CACHE" }) 同名。
成功后双工具链并存:pnpm dev:vinext 与 pnpm dev(原 Next)同时可用。重点验证:认证、middleware、mutations、缓存、部署绑定——别只看首页。
阶段 3:手动迁移(兜底,仅 init 失败时)
- 装包:
vinext+ devDepsvite、@vitejs/plugin-rsc、react-server-dom-webpack、@mdx-js/rollup、@vitejs/plugin-react(版本对齐 vinext peer) - scripts 改造(保留 flag):
next dev/build/start/lint→vite dev/build/vinext start/vinext lint - ESM:
"type": "module"+ CJS 配置改名.cjs - 最小 vite.config:
plugins: [vinext()]
红线:不要自己注册 @vitejs/plugin-rsc——装了即可,vinext 自动注册;手动 rsc() 构建失败 Duplicate @vitejs/plugin-rsc detected。要接管才传 vinext({ rsc: false })。
阶段 4:部署
4.1 Cloudflare Workers(首选,最完整)
# 认证:本地 cf auth login;CI 用 CLOUDFLARE_API_TOKEN(Edit Cloudflare Workers 模板 + traffic-aware 需 Zone Analytics Read)
pnpm exec cf auth login
npx @vinext/cloudflare deploy # 基础部署
npx @vinext/cloudflare deploy --warm-cache # 两段式:0% 流量上传→渲染填缓存→promotion
deploy 核心 flag(实测 --help 全量见 references/config-examples.md §5):
--env <name> / --preview / --skip-build / --dry-run / --no-promote / --warm-cache / --warm-cache-target <origin> / --warm-cache-concurrency 25 / --warm-cache-certify / --traffic-aware-warm-cache(按真实流量预热,默认覆盖 90% 流量,需自定义域名)/ --traffic-aware-coverage 95 / --traffic-aware-limit 500 / --traffic-aware-window 48
> --experimental-tpr / --tpr-* 是 traffic-aware 的旧别名,仍有效但用新名。
绑定(Binding)标准写法:
import { env } from "cloudflare:workers"; // Server Component / Route Handler / Server Action 直接用
const posts = await env.DB.prepare("SELECT * FROM posts").all();
- 绑定声明:新版在
cloudflare.config.ts(import { bindings } from "cf/config");legacy 在wrangler.jsonc - 类型:自动生成到
.cloudflare/types(tsconfig include 要加);独立类型检查前跑cf workers types - 不要用
getPlatformProxy()/getRequestContext()/ 自定义 worker entry - 支持全部绑定:D1/R2/KV/DO/AI/Queues/Vectorize/Browser Rendering/Images/Hyperdrive
4.2 其他平台
Node standalone:next.config 设 output:"standalone" → node dist/standalone/server.js;PORT(3000) / HOST(0.0.0.0)。⚠️ 用 HOST 不是 HOSTNAME。
Nitro(Vercel/Netlify/AWS/Deno/Azure):plugins: [vinext(), nitro()];NITRO_PRESET=vercel|netlify|aws_amplify|deno_deploy|node npx vite build。CI 自动探测。Cloudflare 上优先原生集成。
阶段 5:验证(本地无 Cloudflare 账号也完整可测)
vinext build # 全链路构建
vinext start # 生产服务器冒烟:逐路由 curl 200 + 内容 + 404 页
vinext check # 兼容性
vinext lint # oxlint
node scripts/benchmark.mjs <项目目录> --repeat 3 # 构建性能基线:next build vs vinext build 实测对比
⚠️ 本地 vite dev/vinext dev 可能 404:App SSR 依赖 workerd,无 worker entry 时不挂载 app 路由(框架行为非 bug)。用 vinext start 或 npm run preview 替代本地验证。KV 适配器本地缺绑定时优雅降级(打印 Add VINEXT_KV_CACHE to wrangler.jsonc 提示后回落默认 handler,服务不中断)。
沉淀闭环(每次跑完必做,学自 ima 的「查询→沉淀」范式)
跑完一次闭环不是结束,把新产生的东西固化下来,技能才会越用越准:
node scripts/deploy_summary.mjs # 生成 DEPLOY_SUMMARY.md(项目/命令/产物/路由冒烟结果)
node scripts/benchmark.mjs --repeat 3 # 顺手测构建性能基线,报告随项目落盘
- 新踩坑:追加到
references/learnings.md(格式:日期 / 场景 / 现象 / 根因 / 修复 / 来源)。单坑一分片:一条 L 只记一个坑,不把两个坑混在一条里(学自 ima 动态分片——切片语义完整才能被准确召回)。双路可命中:现象字段必须同时含原始错误串/命令(关键词路)和场景描述(语义路),两条检索路都能捞到。关键经验固化成规则,不留改动痕迹。 - 机械化写入(推荐):
python3 scripts/precipitate.py --scene … --symptom … --root-cause … --fix … --source …——自动 L 编号递增、必填校验、摄入三条件 + 双路可命中软校验、写前备份,格式不对拒绝落盘(--force强制放行并标注警告)。规范由此工具担保,不靠记性。 - 命名与实体互联(学自 ima 知识图谱):沉淀物统一
Vinext固定前缀 + 类型 + 项目名 + 日期(如vinext-deploy-summary-<项目>-<日期>.md);L 编号 ↔ troubleshooting 附-N ↔ 本文件章节互相引用,让跨文档实体可串联。 - 摄入三条件(学自 ima 单一事实来源 + 摄入标准):进 learnings 或 ima 前过筛——与 Vinext 相关、未过时、有实证(【实测】/官方/issue)。宁缺毋滥:垃圾进垃圾出,检索质量上限在输入那一刻已定。
- 回写 ima(可选):首选 WorkBuddy 原生 IMA 通道(设备侧授权即用、无凭证无过期),备选 ima-mcp-server(需 RAG 问答时);命名与摄入规则同上,配置见
references/ima-integration.md。
缓存配置(declarative cache 是官方一等用法)
import { kvDataAdapter } from "@vinext/cloudflare/cache/kv-data-adapter";
vinext({ cache: { data: kvDataAdapter({ binding: "VINEXT_KV_CACHE" }) } });
- 无需自定义 worker entry,插件在首个请求时自动注册并注入 env
- 绑定名默认
VINEXT_KV_CACHE——自定义绑定名必须显式传,且与 wrangler/cloudflare.config 声明一致(1.0 起 namespace 可自动 provision,binding 声明仍要人工核对,见阶段 2 警告) - 适配器选型先于配置:默认
response-store(响应+数据二合一,init 默认推荐);只要整页 ISR 选workers-cache;纯静态选static-assets;data cache 选kv。四类适配器协议、Response Store 双模式(service-binding / self-contained)与 1.1.0 失效语义(soft-invalidate / tag stale / 整页再生)见references/config-examples.md§3 - 本地构建/无绑定环境:适配器声明不触运行时,build 照常通过(实测)
- 区分两种缓存:
--cdn-cache response-store(init 默认)是 CDN 响应缓存(边缘缓存整页响应);DevKit 与上方kvDataAdapter示例是 data cache(KV 绑定缓存数据/片段),两者可并存 - 预渲染口径(1.0 #3340):Worker 部署的 deploy 期预渲染已改 cache warming(0% 流量上传→预热→promotion);
static-assets路径仍是构建期预渲染,别混
已知限制(官方 1.0)
| 功能 | 状态 |
|---|---|
| Cache Components/PPR | "use cache" 部分实现,完整 cacheComponents 未对齐 |
next/image 构建期优化 |
无;远程 @unpic,Cloudflare 上可加 imagesOptimizer |
next/font/google |
CDN 加载,非自托管 |
| 域名 i18n | 不支持;path-prefix 可用 |
next/jest |
用 Vitest |
| Turbopack/webpack 配置 | 忽略;用 Vite 插件(Vite 8 优先 oxc/rolldownOptions) |
preferredRegion |
忽略;runtime 不决定运行位置 |
行为差异(高频踩坑):
- 动态判定在渲染中发生:"use client" 页读 searchParams / 无 Suspense 的 useSearchParams() 可能不被识别为动态 → 对齐做法:layout 导出 dynamic="force-dynamic" 或 useSearchParams() 包 <Suspense>
- SSG 分类不跑 generateStaticParams → 把它放最后一个动态段(哪怕返回 []),两边都静态
- dotenv:vite dev 不预加载 .env(vinext dev 会)→ config 期变量用 loadEnv()
反模式(绝对不要)
- 改
app/、pages/、应用代码;把next/*改写成vinext/* - 手动注册
@vitejs/plugin-rsc(Duplicate detected 构建失败) - 用
getPlatformProxy()/ 自定义 worker entry 取绑定 - 跳过
vinext check - 忽略 Node 版本就开跑(低于 22.18.0 必炸,见环境预检)
- 以为
--data-cache=kv会自动建好 KV 绑定(不会,必须手动创建回填) - 照抄 CLI 命令当 npm script(脚手架 script 名不同,见速查表)
- Tailwind v4 用 postcss 配置(与 Vite 内置 postcss-import 冲突)——用官方
@tailwindcss/vite插件 - 本地验证只试
vite dev就下结论(会 404)——用vinext start - Cloudflare 上优先 Nitro 而非原生集成
- 引用
vinext/cloudflare子路径(不存在!适配器全在@vinext/cloudflare/cache/*、images/*)
配套资源
references/compatibility.md—— 实时兼容数据 + 33 个 shim 清单 + 行为差异详解references/config-examples.md—— vinext() 全选项 / 4 缓存适配器 / cf 新范式 / deploy 全 flag / 多平台references/troubleshooting.md—— 14+3 类常见错误与修复(含本次从零落地实测坑)references/learnings.md—— 经验技巧自积累(每次实测新坑追加这里,呼应 ima Agent 经验模块)references/ima-integration.md—— ima 知识库联动(原生通道首选 + MCP 备选 + RAG 技术机制迁移 + Skills 广场)references/devkit.md—— Vinext DevKit v1.1.0 套件联动(新项目 5 分钟起步)references/fullstack-nestjs.md—— 路径 D 从 0 开发全栈项目操作手册(NestJS 12 ESM + TypeORM + Vite 前端,S1-S7 全流程 + 实测坑)references/setup-guide.md—— 依赖配置指南(Node/vinext/Cloudflare/ima 四依赖的安装、登录、凭据、轮换)skill-dependencies.json—— 机器可读依赖清单(检查项 + 功能降级映射)scripts/detect_env.py—— 环境一键探测(Node 版本/包管理器/平台)scripts/deploy_summary.mjs—— 生成部署摘要scripts/benchmark.mjs—— 构建性能基线实测(next build vs vinext build 同口径计时 + 报告落盘)scripts/precipitate.py—— 沉淀机械化(learnings 条目合规写入:编号递增/三条件校验/写前备份)scripts/check_environment.py—— 标准位只读环境检查器(读 skill-dependencies.json,输出 ready/partial/needs_setup/unavailable 路由)test/—— 测试套件:6 个套件 / 35 条断言全绿(detect_env / deploy_summary / check_environment / precipitate / benchmark / fullstack_path;跑法:python3 -m unittest discover -s test -v)- 官方:https://vinext.dev | https://github.com/cloudflare/vinext | https://vinext.dev/compatibility
> 版本溯源:本技能由 cloudflare/vinext 官方资料源码级调研 v2 + 从零落地实测沉淀 + ima 知识库 RAG 技术机制提炼 + 1.0 GA/1.1.0 官网与 release notes 复核 + 性能基线与沉淀机械化能力共同构成(v1.0 初版至今的 source 记录)。v3.0.0:扩为全栈落地大家庭——新增「从 0 开发全栈项目」路径 D(NestJS 12 ESM + TypeORM + Vite 前端,现场实证全链路跑通:脚手架/迁移/生产冒烟),新增 references/fullstack-nestjs.md 操作手册与 test_fullstack_path.py 测试套件(6 套件 / 35 条断言),learnings 新增 NestJS ESM 五坑沉淀。v2.4.2:drama-board 演示项目全流程实测,learnings 新增 L-010(nvm install 不切当前 shell,agent 每步需 nvm use)、L-011(useSearchParams 页 curl 冒烟只看得到 fallback,水合内容须 headless Chromium 验证)。v2.4.1:frontmatter 升级为平台顶层九项字段格式 + 补测试套件声明,正文行为不变。