Supabase 文档站构建管线解析:Turborepo、pnpm 生命周期钩子与 codegen 协同工作流 Supabase 文档站构建管线解析Turborepo、pnpm 生命周期钩子与 codegen 协同工作流【免费下载链接】supabaseThe Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications.项目地址: https://gitcode.com/GitHub_Trending/supa/supabase本文以apps/docsSupabase 文档站的构建管线为主体结合仓库中的turbo.jsonc、package.json脚本与实际 codegen 源码完整拆解“依赖包构建 → 示例/参考文档代码生成 → Next.js 构建 → sitemap 与 CDN 上传”的全链路流程。读完本文你能理解文档站每次pnpm build背后各步骤的触发顺序、Turbo 缓存策略的关键配置以及如何为文档应用安全地新增构建步骤与环境变量。1. 管线总览Turborepo 与 pnpm 两层编排apps/docs的构建由两层机制协同完成Turborepo根 turbo.jsonc 与 apps/docs/turbo.jsonc负责按依赖顺序编排工作区任务声明inputs/outputs/env实现缓存pnpm 生命周期钩子apps/docs/package.json在next build前后通过prebuild/postbuild脚本插入 codegen 与资产上传步骤。整体数据流为依赖包 build^buildcommon、ui、config、icons … ↓ codegen:examples复制 ../../examples → apps/docs/examples codegen:references→ features/docs/generated/** build:markdownguides reference 的 .md 导出 ↓ docs#buildpnpm prebuild 链 → next build → pnpm postbuild 链 ↓ build:sitemap → upload-static-assets.shR2 CDN仅生产风格部署从源码结构看Turbo 层只声明到build:markdown而build:federated-content、build:gz-archive等步骤则由 pnpm 的prebuild在next build前串行执行——两层机制的职责边界清晰跨包依赖与缓存归 Turbo包内前后置步骤归 npm 生命周期。2. 从仓库根目录触发的命令根 package.json 中与文档站直接相关的脚本以当前仓库实际内容为准build: turbo run build, build:docs: turbo run build --filterdocs, dev:docs: turbo run dev --filterdocs --parallel, test:docs: turbo run test --filterdocs全量构建pnpm build→turbo run build按依赖序构建所有包与应用。仅构建文档站pnpm build:docs→turbo run build --filterdocsTurbo 会先解析docs的^build依赖闭包再执行文档站自身任务。本地开发pnpm dev:docs或在apps/docs下pnpm dev。运行环境前提见根 package.json 的engines/packageManagerpnpm 11.13、Node 22.13且preinstall通过only-allow pnpm强制使用 pnpm。3. Turbo 层做了什么3.1 根 turbo.jsonc^build保证依赖先构建根 turbo.jsonc 定义build: { dependsOn: [^build], outputs: [dist/**, .next/**, !.next/cache/**/*, !.next/dev/**/*], }dependsOn: [^build]意味着docs的所有工作区依赖common、ui、config、icons、shared-data、ai-commands等见 apps/docs/package.json 中workspace:*依赖列表会在docs之前完成构建。全局缓存保留期由cacheMaxAge: 14d控制。3.2 apps/docs/turbo.jsonc扩展并收紧 docs 任务apps/docs/turbo.jsonc 通过extends: [//]继承根配置并为文档站细化任务codegen:examples: { inputs: [../../examples/**], outputs: [examples/**], }, codegen:references: { inputs: [spec/**], outputs: [features/docs/generated/**], }, build:federated-content: { cache: false, env: [ DOCS_GITHUB_APP_ID, DOCS_GITHUB_APP_INSTALLATION_ID, DOCS_GITHUB_APP_PRIVATE_KEY, ], }, build:markdown: { dependsOn: [build:federated-content], outputs: [public/markdown/**, public/markdown/manifest.json], }, build: { dependsOn: [^build, codegen:examples, codegen:references, build:markdown], env: [ /* 约 50 个变量见下文 */ ], inputs: [$TURBO_DEFAULT$], outputs: [.next/**, !.next/cache/**], }几个值得注意的设计决策源码注释原文佐证codegen:examples/codegen:references显式声明 inputs/outputs这样 Turbo 才能对其缓存——例如examples/目录或spec/目录无变化时直接恢复产物apps/docs/examples/**、features/docs/generated/**。build:federated-content关闭缓存任务注释明确说明“输入是远端GitHub内容缓存恢复可能复活陈旧内容”故cache: false。该脚本为 apps/docs/scripts/federated-content/fetch-federated-content.ts依赖 GitHub App 三元组环境变量。build:markdown声明 outputs注释解释“若声明了 outputs缓存命中时 Turbo 可恢复这些产物否则缓存命中会跳过脚本导致next build找不到生成的 markdown”。这是典型的 Turbo 缓存陷阱有副作用/产物的任务必须声明outputs。build任务的 env 清单列出约 50 个影响产物的环境变量NEXT_PUBLIC_SUPABASE_URL、NEXT_PUBLIC_SITE_URL、NEXT_PUBLIC_IS_PLATFORM、VERCEL_ENV、DOCS_GITHUB_APP_*、OPENAI_API_KEY、SUPABASE_SECRET_KEY等。任何影响构建产物但未列入env的变量都会导致 Turbo 缓存出陈旧产物——新增环境变量时必须同步加入此清单官方文档 build-pipeline.md 将其列为改动守则之一。Turbo 为 docs 编排的完整顺序即依赖包 → 示例/参考 codegen → markdown 导出 → Next 构建。4. pnpm 生命周期层prebuild/build/postbuildapps/docs/package.json 中实际的生命周期脚本当前仓库版本注意比早期文档多出一步build:federated-contentprebuild: pnpm run codegen:graphql pnpm run codegen:references pnpm run codegen:examples pnpm build:federated-content pnpm run build:markdown pnpm run build:gz-archive, build: next build, postbuild: pnpm run build:sitemap ./../../scripts/upload-static-assets.sh执行语义turbo run build --filterdocs最终执行docs#build时pnpm 自动先跑prebuild再跑next build最后跑postbuildprebuild 五六步GraphQL codegen → 参考文档 codegen → 复制 examples → 拉取 federated 内容 → 生成 guides reference 的 markdown 导出 → 打包 tar.gzbuildnext buildANALYZEtrue时可换成build:analyze做包体积分析;postbuild生成 sitemap随后调用仓库根目录的 scripts/upload-static-assets.sh仅生产风格部署上传 R2。5. 逐个 codegen 脚本详解脚本实际命令产物 / 作用codegen:graphqltsx --conditionsreact-server ./scripts/graphqlSchema.ts graphql-codegen --config codegen.ts拉取/固化 GraphQL schema 并用 graphql-codegen 生成类型codegen:examplesshx cp -r ../../examples ./examples把 monorepo 根examples/复制进apps/docs/examples供 MDX 中$CodeSample指令解析示例代码codegen:referenceslegacynew两段式见下文build:federated-contenttsx … ./scripts/federated-content/fetch-federated-content.ts通过 GitHub App 拉取远端内容并产出 JSON 工件供 markdown 生成器读取build:markdownbuild:guides-markdown build:reference-markdown生成public/markdown/guides/**.md与public/markdown/reference/**.mdbuild:gz-archivetsx ./internals/generate-gz-archive.ts打包public/markdown/为public/docs.tar.gzbuild:sitemaptsx ./internals/generate-sitemap.ts生成站点 sitemappostbuild 阶段5.1 参考文档 codegen 的双轨结构codegen:references实为两条管线串行codegen:references:legacy: tsx features/docs/Reference.generated.script.ts, codegen:references:new: pnpm run codegen:references:new:ensure tsx scripts/build-reference-content.tslegacy 轨apps/docs/features/docs/Reference.generated.script.ts 处理 Management API——将 OpenAPI v1v2 合并为api.latest.*JSON规格下载/合并由 apps/docs/spec/MakefileRedocly完成。相关背景见 management-api-reference.md。new 轨ensure步骤先校验三份 TSDoc JSONspec/reference/javascript/v2/supabase.json、spec/reference/server/v1/server.json、spec/reference/middleware/v1/middleware.json缺失时调用make download.*目标下载随后 apps/docs/scripts/build-reference-content.ts 从spec/reference/下的 TSDoc JSON 构建参考内容输出落在features/docs/generated/**这正是 Turbo 声明的codegen:referencesoutputs。此外还有precodegen:references:new钩子会顺带生成 Dart 参考codegen:references:dart。5.2 markdown 导出管线guidesapps/docs/internals/generate-guides-markdown.ts 遍历content/guides/**/*.mdx基于mdast/micromarkGFM MDX 扩展、gray-matterfrontmatter 解析将大量自定义 MDX 组件markdown-schema/下的Admonition、StepHike、TabPanel、PromptPanel、RegionsList等约 30 个映射逐一降级为纯 Markdown并借助 internal-links.ts 重写内部链接为带 base path 的绝对路径产物为public/markdown/guides/**.md。referenceapps/docs/internals/generate-reference-markdown.ts 对features/docs/generated/**的参考内容执行同类导出产物为public/markdown/reference/**.md。归档apps/docs/internals/generate-gz-archive.ts 用tar将public/markdown/全部条目排序后压缩为public/docs.tar.gz源码注释强调排序条目 portable 头以保证确定性输出随站点静态资源在/docs/docs.tar.gz提供服务。这一套“运行时页面”与“纯 Markdown 导出”并行输出的结构即文档中提到的LLM/Agent 消费面——Agent 直接读取 markdown 与 tar.gz 而非爬取 HTML详见 llm-agent-surface.md 与 app-map.md。6. postbuildsitemap 与 R2 CDN 上传postbuild的第二步是仓库根目录共享的 scripts/upload-static-assets.sh要点以脚本源码为准触发条件仅当FORCE_ASSET_CDN1或VERCEL_ENVproduction时执行FORCE_ASSET_CDN-1如 Studio 自托管场景显式跳过。本地与 preview 部署均不上传。桶选择NEXT_PUBLIC_ENVIRONMENTstaging时上传frontend-assets-staging否则frontend-assets-prodCloudflare R2通过ASSET_CDN_S3_ENDPOINT自定义 endpoint 走 S3 协议。路径设计s3://bucket/SITE_NAME/VERCEL_GIT_COMMIT_SHA 前 12 位/_next/static按环境 应用 提交哈希隔离旧版本资产留存一段时间以避免切换瞬间的“抖动”。缓存策略--cache-control public,max-age604800,immutable7 天不可变缓存同时同步.next/static与public/public 上传是因为部分文件会被 CSS 相对路径引用需走 CDN URL。目的脚本头部注释绕开 Vercel 出口流量费、规避 Cloudflare 代理的 Orange-to-Orange 超时问题、避免双重 TLS 终结带来的额外延迟。7. 本地开发模式在apps/docs下或根目录pnpm dev:docspnpm dev # http://localhost:3001/docs相关脚本apps/docs/package.jsondev: run-p --race dev:next dev:watch:troubleshooting, dev:next: next dev --port 3001, dev:watch:troubleshooting: node ./scripts/troubleshooting/watch.mjs, predev: pnpm run codegen:graphql pnpm run codegen:references pnpm run codegen:examples, dev:secrets:pull: AWS_PROFILEsupa-dev node ../../scripts/getSecrets.js -n local/docspredev先跑 GraphQL / reference codegen 与 examples 复制不含 markdown 导出与归档加快启动。并发 watcherdev:watch:troubleshooting通过 apps/docs/scripts/troubleshooting/watch.mjs 同步 troubleshooting 内容数据源为远程 schema见supabase/migrations中troubleshooting_entries相关迁移。社区贡献者在.env中设置NEXT_PUBLIC_IS_PLATFORMfalse。内部环境pnpm run dev:secrets:pull从 AWS Secrets Manager 拉取依赖 scripts/getSecrets.js 与 AWS profile。按需渲染dev 模式下应用仅在被请求时构建路由不做预渲染preview 与 production 环境在构建期静态生成路由以保证访问速度。8. 生产部署 vs CI生产构建文档站由 Vercel 部署apps/docs/vercel.json 仅一行——buildCommand: pnpm build——即执行上文 docs 应用的完整 prebuild/build/postbuild 脚本链。GitHub Actions主要运行test:docsTurbo 编排的 vitestDOCS_SMOKE_URL环境变量可让 smoke 测试指向 preview 或 localhost 而非生产见 turbo 中test任务的 env 声明、lint、内容同步与 smoke 检查并不在 CI 侧重复一套完整生产构建图。工作流面细节见 ci-and-lint.md。9. 改动守则为什么这套结构对变更敏感官方参考文档 build-pipeline.md 给出的三条守则均可在仓库中找到对应落点新增构建步骤优先检查prebuild/postbuild是否已有可复用的钩子“复用管线不要分叉管线”见 adding-features.md跨包产物应注册为 Turbo 任务并声明inputs/outputs。新增环境变量必须加入 apps/docs/turbo.jsonc 的env列表否则 Turbo 哈希不包含该变量会命中陈旧缓存——这是该管线最常见的坑。触碰 markdown 导出先阅读 app-map.md 中“两条管线”一节——运行时页面与 markdown 导出共享数据源但不共享代码路径修改 MDX 组件时两条导出路径都需回归public/markdown/manifest.json与 tar.gz 内容都要验证。此外若行为与预期不符官方建议直接以 apps/docs/turbo.jsonc 与 apps/docs/package.json 的当前内容为准核对——本文所列脚本链含build:federated-content这一步即按当前仓库实际版本整理与旧版参考文档中的简化描述可能存在差异。10. 小结Supabase 文档站的构建管线是一个“Turborepo 管依赖与缓存、pnpm 生命周期管前后置步骤”的教科书式 monorepo 案例^build保证工作区依赖先行codegen:examples/codegen:references/build:markdown以显式 inputs/outputs 接入 Turbo 缓存prebuild串起 GraphQL 类型、双轨参考文档生成、federated 内容拉取与 Markdown/tar.gz 导出next build完成页面构建postbuild收尾 sitemap 并按VERCEL_ENVproduction条件将静态资产推上 Cloudflare R2。理解这条链路后无论是新增文档生成步骤、接入新环境变量还是排查“缓存命中但产物缺失”这类问题都能定位到 apps/docs/turbo.jsonc、apps/docs/package.json 及 apps/docs/internals/ 下的对应脚本。【免费下载链接】supabaseThe Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications.项目地址: https://gitcode.com/GitHub_Trending/supa/supabase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考