本地开发与构建
按依赖、初始化、开发请求、内容生成和生产构建的顺序定位本地问题。
先区分问题发生在安装依赖、执行脚本、启动服务器,还是打开页面以后。服务器能监听端口,不代表配置加载、数据库访问和页面渲染都已经成功。
一、确认目录和运行环境
所有命令都在 CLI 创建的应用项目根目录执行,不是在 saavo-cli 或文档网站仓库执行。不同仓库的 package.json 不同,不能直接套用它们的部署命令。
node --version
npm --version当前模板检查要求 Node.js 至少为 22.13.0,检查脚本建议使用 Node.js 24。更换版本后,重新打开终端,确认实际使用的版本已经切换。
如果看到 Missing script,先检查当前目录的 package.json。初始化源码包不包含模板维护者的 commit script,应用也没有默认的 deploy:prod script。完整列表见项目命令。
二、安装失败时保留锁文件
初次从发布源码包创建项目时可能没有 package-lock.json,使用:
npm install如果已有有效且与 package.json 一致的锁文件,希望按锁定版本重新安装,可以使用 npm ci。该命令会重新安装依赖,锁文件不一致时会停止。
安装失败时先判断错误类别:
| 现象 | 检查方向 |
|---|---|
| 网络超时、连接被拒绝 | 包源、代理、网络访问情况 |
| Node.js 版本不匹配 | 当前终端版本,而不是只看已安装版本 |
| 文件被占用、访问被拒绝 | 开发服务器、编辑器或其他进程是否正在使用文件 |
| 锁文件与依赖声明不一致 | 是否有遗漏的依赖修改,确认后再更新锁文件 |
| 原生依赖或平台包加载失败 | 是否从另一台机器复制了 node_modules,应在当前平台安装 |
不要把删除锁文件或执行强制依赖升级当作通用修复,这会同时改变许多依赖,难以判断原始问题是否解决。
三、补完本地初始化
依赖安装成功后执行:
npm run saavo:init执行顺序是:
创建或保留 .env,补充缺失的 SAAS_SECRET
→ cf-typegen
→ db:migrate:local
→ doctor该命令不会覆盖已有的有效主密钥,不会创建远程 Cloudflare 资源。如果在数据库步骤失败,前面的 .env 和类型文件可能已经生成。应修复当前错误后继续,不必删除整个项目重新创建。
初始化后 .env 中的第三方服务凭据仍可能为空。doctor 对 Stripe 或 OAuth 的提示不能直接解释成整个应用初始化失败,应先看最终错误数,再判断当前是否需要该服务。
如果 SAAS_SECRET 存在但格式错误,脚本不会替你随意更换。新项目应修正为有效配置,已有数据的项目应先找回原始密钥,不能直接覆盖。
四、开发服务器无法启动或打开页面返回 500
npm run dev始终使用终端实际显示的地址和端口。项目会按开发服务器端口生成本地站点地址,不需要为了端口变化反复修改 .env 的 VITE_SITE_URL。
| 最早出现的错误 | 处理方式 | 验证结果 |
|---|---|---|
| 找不到模块 | 完成依赖安装,确认没有复制其他平台的依赖目录 | 原模块错误消失 |
| 配置启动校验失败 | 按报错字段检查 config/ 及其引用 | 能通过 npm run doctor 的配置加载 |
| 缺少 Binding | 核对 wrangler.jsonc,必要时运行 cf-typegen | 运行时能访问对应资源 |
no such table | 确认本地数据库并执行本地迁移 | 同一页面不再报缺表 |
| 页面请求返回 500 | 结合请求时间查看终端异常栈 | 同一请求返回预期页面或业务响应 |
cf-typegen 只生成类型声明。编辑器不再报错,不等于运行时的 Binding 已经存在。也不要把 Cloudflare 资源访问临时替换成内存对象来隐藏配置问题。
本地 D1、KV 等状态与远程资源独立。删除 .wrangler 状态目录可能清空本地数据,排错前应先确认是否需要保留。
五、配置字段正确,但组合不成立
项目使用 TypeScript 与 Zod 两层检查。常见问题包括产品引用已删除的角色、联盟规则引用不存在的套餐、时间间隔格式不合法,以及把 LocalizedText 写成普通字符串。
先找到错误指向的配置项,再向它引用的对象查找。例如修改产品 ID 后,还要检查联盟推广、页面和升级建议是否继续使用旧 ID。不要用 as any 绕过校验。
字段类型和当前默认值见配置文件。前面的构建教程可能使用自成体系的示例名称,移植到自己的项目时需要统一引用,不能只复制一个配置片段。
六、文档、博客或搜索没有更新
内容更新涉及三个位置:源文件、构建生成的集合与搜索索引,以及运行时读取的 KV 内容。
npm run gen:collections这一步用于检查 MDX 是否能编译。出现错误时,按文件名和行号检查 Frontmatter、未闭合的 JSX、代码围栏和组件属性。导航不显示时再核对 meta.json、语言目录和 deploy.content 开关。
需要更新搜索索引时运行:
npm run gen:search-index如果当前问题是正文仍读取到旧的本地 KV 内容,再运行:
npm run kv:sync:local以上操作用途不同,重新生成集合不会自动证明远程 KV 已更新。线上内容问题见部署、资源与域名。
七、开发正常,预览或构建失败
npm run preview模板的预览命令会先执行 build:preview,再使用 127.0.0.1:4173 进行本地预览。预览经过打包流程,不能假定所有行为都与 npm run dev 相同,尤其是邮件发送、环境变量和仅在生产模式执行的检查。
需要单独定位检查阶段时运行:
npm run lint
npm run typecheck
npm run buildVite 可以在不完成完整类型检查的情况下生成产物,构建成功不能代替 typecheck。修复代码后,用 npm run verify 完成项目全部检查。
以退出码和实际失败步骤判断结果。有些日志只是警告,但也不要因为最后看到了构建文件列表,就忽略前面出现的类型、内容生成或文件写入错误。
修复后的验证
重新启动项目,完成原来失败的页面操作。如果改动涉及内容,再分别检查导航、正文和搜索。如果改动涉及初始化,再确认原有本地账号和数据仍然可用,避免通过清空状态得到看似成功的结果。