gatsby-source-wordpress 预览(Preview)机制完全指南:配置、运行原理与源码级解析

发布时间:2026/9/21 3:01:25
gatsby-source-wordpress 预览(Preview)机制完全指南:配置、运行原理与源码级解析 前端静态站点Web框架【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址https://gitcode.com/gh_mirrors/ga/gatsby点击查看免费下载导读本文基于 packages/gatsby-source-wordpress/src/steps/preview/preview.md 展开系统讲解 Gatsby 生态中 WordPress 内容预览CMS Preview的完整链路从环境准备、插件版本要求、Gatsby Cloud 与 WPGatsby 的对接配置到「点击预览 → Webhook → 拉取草稿数据 → 生成页面 → 回传状态 → iframe 呈现」的端到端运行原理。读完本文你将掌握 WordPress 后台一键预览 Gatsby 页面所需的全部配置步骤、常见踩坑点以及该机制在gatsby-source-wordpress源码中的真实实现位置与调用关系。一、功能概览与前置条件CMS Preview 是 Gatsby 面向内容编辑者的核心工作流编辑在 WordPress 后台点击「预览」系统会实时拉取尚未发布的草稿/修订数据在 Gatsby 预览实例上构建出对应页面并回显。要让这套流程跑通需要同时满足两端的前置条件Gatsby 侧预览实例一个运行在Gatsby Cloud上、且已启用CMS Previews的 Gatsby 站点站点通过gatsby-source-wordpress从 WordPress 拉取数据即插件配置中的url选项必须指向 WordPress 实例的/graphql端点例如https://example.com/graphql。WordPress 侧内容源一个公网可访问的 WordPress 实例安装WPGraphQL v0.15.0提供 GraphQL API 与asPreview修订查询能力安装WPGatsby v0.6.0负责监听保存动作、发送 Preview Webhook 并提供wpGatsbyRemotePreviewStatus变更接口。从源码结构看gatsby-source-wordpress的预览逻辑全部收敛在 src/steps/preview/ 目录下index.ts预览拉取主流程、on-create-page.ts页面创建期回调、cleanup.ts残留回调清理、preview.md使用文档。后续章节将逐一对齐源码与文档描述。二、配置步骤从零接通 WordPress 后台预览按以下顺序操作即可完成最小可用的预览配置确认插件与端点配置在gatsby-config.js中确认gatsby-source-wordpress的url已指向 WordPress 的 GraphQL 端点例如module.exports { plugins: [ { resolve: gatsby-source-wordpress, options: { url: https://your-wp-site.example.com/graphql, }, }, ], }打开 Gatsby Cloud 的 CMS Previews 标签页触发第一次 Preview 构建需确保上述插件版本均已满足要求。复制预览前端地址在已完成的 Preview 构建列表顶部复制预览实例的 front-end URL。填写 WPGatsby 设置进入 WordPress 的 WPGatsby 设置页将上一步复制的 Preview frontend url 粘贴进去。复制 Preview Webhook回到 Gatsby Cloud 的 Site Settings 标签页滚动到 webhook 区域复制 Preview webhook。回填 Webhook 地址将 Webhook 粘贴到 WPGatsby 设置中对应的 Preview webhook 字段。触发预览在 WordPress 中打开任意文章或页面像平时一样点击「预览」。观察结果如果配置有误预览窗口会直接显示带有后续处理步骤的错误提示配置正确时会先出现加载动画待预览就绪后自动揭开页面。需要说明上述步骤依赖 Gatsby Cloud 提供的 CMS Previews 托管环境仓库源码本身只负责消费 WPGatsby 发来的 Webhook 与previewData并不涉及 Gatsby Cloud 控制台的具体操作界面。三、已知限制与注意事项Caveats文档明确列出两点容易踩坑的限制务必提前知晓1. Gutenberg 与 ACF 无法在预览中共存Gutenberg 会破坏 ACF 的预览这并非 Gatsby 或 WPGatsby 引入的问题而是 WordPress 侧两者的兼容性限制。因此如果需要在预览中看到 ACF 自定义字段数据就不能在编辑器中使用 Gutenberg例如改用经典编辑器。2. 页面必须携带 node id 到 pageContext要成为「可预览页面」你在创建页面时必须把对应节点的id放进pageContext否则预览窗口会显示配置错误提示。这是源码层面的硬性要求onCreatepageSavePreviewNodeIdToPageDependency正是通过page.context page.context.id getNode(page.context.id)来反查「创建该页面的节点」从而建立 nodeId → 页面的映射关系见 src/steps/preview/on-create-page.ts。典型做法是在gatsby-node.js中创建页面时显式写入exports.createPages async ({ actions, graphql }) { const { createPage } actions const result await graphql(/* GraphQL */ { allWpPost { nodes { id uri } } } ) result.data.allWpPost.nodes.forEach(node { createPage({ path: node.uri, component: path.resolve(./src/templates/post.js), context: { // 关键把节点 id 写入 pageContextPreview 才能定位该页面 id: node.id, }, }) }) }源码注释中承认目前还没有足够可靠的方式自动探测页面与节点的依赖关系因此pageContext.id是当前版本唯一稳定的约定见 on-create-page.ts 的实现说明。四、内部工作原理一次预览的完整生命周期文档描述了一套「Webhook 驱动 状态回传」的异步闭环。结合源码可将它拆解为以下阶段阶段 1用户在 WordPress 后台按下「预览」WPGatsby拦截预览动作并进行前置判定判断这是新预览、草稿、常规文章更新还是重复请求。若是新预览则向 Preview 实例发送 Webhook。阶段 2save_post 防抖每篇文章粒度Preview 的save_post调用是按文章去抖的同一篇文章在5 秒窗口内触发的多个 Webhook 只会合并发送一个避免高频构建。不同文章同时预览时目前仍会各自触发构建源码中对应previewForIdIsAlreadyBeingProcessed的按 id 去重逻辑见 index.ts但预览加载逻辑在这种并发场景下依然可用。阶段 3Webhook 携带的数据Preview Webhook 通过 POST 携带以下信息与源码中IPreviewData接口逐项对应见 index.ts字段含义源码接口字段JWT Token供 Gatsby 查询私有预览修订数据的凭据token父级数据库 id修订版本所属文章的 database idparentDatabaseId是否新文章草稿标记本次预览是否针对新草稿isDraft被预览节点的类型如Post/Page的 singleNamesingleName被预览修订或草稿的 id唯一标识本次预览对象id/previewDatabaseId发送方 WordPress 实例的 URL用于校验数据来源remoteUrl修订是否被禁用影响数据拉取策略对应asPreview查询行为节点修改时间用于判断页面数据新旧modifiedpreview: true标记本次为预览数据源插件据此走预览分支preview其中userDatabaseId与token会作为请求头WPGatsbyPreview/WPGatsbyPreviewUser透传给 WPGraphQL见 index.ts。阶段 4WPGatsby 记录发送结果WPGatsby 会记录 Webhook 是否发送成功供前端「乐观加载」预览界面使用若 Webhook 发送失败预览实例离线则把错误写入 WP 的 debug log。阶段 5Gatsby 侧接收并分发sourceNodes刷新分支在 Gatsby 侧sourceNodes以刷新refresh方式被调用当 Webhook body 同时携带token与userDatabaseId时插件判定这是一次预览请求转而调用sourcePreviews而非常规的节点全量拉取见 src/steps/source-nodes/index.ts。sourcePreviews会先向actionMonitorActions查询previewStream: true、status: PRIVATE的待处理动作只取最近 60 分钟内产生的动作已处理的动作会在 WP 侧被删除见 index.ts再对每个动作调用sourcePreview。sourcePreview是单节点预览的入口index.ts其核心行为包括校验必填字段previewDatabaseId、id、token、remoteUrl、parentDatabaseId、modified、userDatabaseId缺失时打印警告并中止调用touchValidNodes()保持既有节点不被 GC 回收通过fetchAndCreateSingleNodeactionType: PREVIEWisPreview: true拉取单个节点——该函数会根据isPreview !isDraft选择previewQuery而非普通nodeQuery因为初始空草稿用常规查询更稳妥见 src/steps/source-nodes/update-nodes/wp-actions/update.js修订节点缺少slug时回退使用节点 id 作为 slug避免依赖 slug 构建 URL 的站点失效update.js对比既有节点忽略修订版本中会无意义变化的字段如日期类字段减少 Gatsby 端查询失效范围update.js通过subscribeToPagesCreatedFromNodeById把「预览状态回调」登记进内存 store等待页面创建后触发。预览任务的并发由PQueue控制并发数取插件选项schema.previewRequestConcurrency见 index.ts。阶段 6URL 来源校验sourcePreviews会比较webhookBody.remoteUrl的 hostname 与插件配置url的 hostname。若两者不一致立即通过回调向 WPGatsby 回传RECEIVED_PREVIEW_DATA_FROM_WRONG_URL状态并打印警告见 index.ts防止从错误的 WordPress 实例混入数据。阶段 7内存回调与状态回传插件在内存中保存一个回调触发后会把预览状态通过wpGatsbyRemotePreviewStatusmutation 回传给 WPGatsby见 index.ts。回传的status与context数据即PreviewStatusUnion的四种取值之一index.tsPREVIEW_SUCCESSNO_PAGE_CREATED_FOR_PREVIEWED_NODEGATSBY_PREVIEW_PROCESS_ERRORRECEIVED_PREVIEW_DATA_FROM_WRONG_URL阶段 8onCreatePage中的两件事当页面创建时onCreatePage会依次执行两个函数见 on-create-page.tsonCreatepageSavePreviewNodeIdToPageDependency预览模式下读取page.context.id反查节点把「nodeId → 页面path updatedAt」存入previewStore.nodeIdsToCreatedPages同时维护pagePathToNodeDependencyId反查表。为保证性能这正是文档强调「pageContext 中必须有 node id」的原因。onCreatePageRespondToPreviewStatusQuery检查当前页面对应节点是否注册了预览状态回调。若存在则以PREVIEW_SUCCESS状态调用该回调把页面路径回传给 WP随后从 store 中移除回调确保只调用一次。此外它还会把节点的modified时间写入page.context.__wpGatsbyNodeModified并重建页面使 WP 侧能判断最新页面是否已部署on-create-page.ts。阶段 9兜底触发点两处额外的回调调用onPreExtractQueries处理尚未被onCreatePage消费的「残留回调」。残留意味着被预览节点没有生成对应页面——要么页面创建时没写 node id 到 pageContext要么根本没有为该节点创建页面。此时以NO_PAGE_CREATED_FOR_PREVIEWED_NODE状态调用这些回调WPGatsby 会展示调试与修复步骤见 cleanup.ts。runSteps的错误边界sourcePreviews结束时会调用invokeAndCleanupLeftoverPreviewCallbacks把仍未消费的回调以GATSBY_PREVIEW_PROCESS_ERROR状态统一清理见 index.ts并在context属性中附带错误发生在哪个步骤的通用信息WPGatsby 据此提示用户检查预览日志。阶段 10前端呈现与状态机预览数据源侧的工作完成后WPGatsby 前端模板进入状态机预览拉取通过 WPGraphQL 的asPreviewAPI 完成若成功创建页面上述onCreatePage逻辑会顺带更新 WPGatsby 中的预览状态与此同时 WP 已打开预览模板若 Webhook 返回204/200则乐观加载 Gatsby 品牌加载动画若返回其他状态码则提示「预览实例离线」两种情况下都会通过浏览器二次探测真实在线状态因为 Webhook 不一定在预览窗口每次加载/刷新时都被命中加载超过45 秒会在动画下方显示警告并给出「取消并排查」cancel and troubleshoot按钮点击后停止等待并展示调试步骤WPGatsby 配置错误未设置 Preview frontend url / Webhook或当前文章类型未在 GraphQL 中暴露时加载另一套错误模板展示修复指引前端收到任何非PREVIEW_SUCCESS状态都会显示错误并移除加载动画收到PREVIEW_SUCCESS附带可访问路径后iframe 指向「预览前端地址 路径」iframeloaded事件触发后移除加载器正式揭开预览页面。五、性能与开发体验优化按需 Schema 对比为了让预览更快文档明确说明预览数据拉取前不再预先 diff 本地与远端 schema。取而代之的是更新预览时捕获 GraphQL 错误再触发 schema 对比若发现 schema 不同则重新生成节点拉取查询并重新拉取预览数据。收益是在 WPGraphQL 中删除某个字段不会破坏预览除非该预览恰好查询了这个被删字段。相关实现位于 schema 对比逻辑中——通过持久化缓存的 schema MD5 判断是否变化schemaWasChanged变化时重新执行createSchemaCustomization见 src/steps/ingest-remote-schema/diff-schemas.js 与 src/steps/ingest-remote-schema/build-queries-from-introspection/build-node-queries.js。基于同一机制该能力被顺带扩展到所有gatsby develop场景只要从 WPGatsby 收到任意 action插件就会 diff schema若发现差异则重新执行createSchemaCustomization拉取最新 schema 并更新 Gatsby 查询。这意味着更新远端 schema 后无需重启 Preview 实例或gatsby develop开发体验显著提升。六、预览模式判定与调试源码通过inPreviewMode()判定当前进程是否处于预览模式index.tsconst inDevelopPreview process.env.NODE_ENV development !!process.env.ENABLE_GATSBY_REFRESH_ENDPOINT const inPreviewRunner process.env.RUNNER_TYPE PREVIEW || process.env.RUNNER_TYPE INCREMENTAL_PREVIEWS || !!process.env.IS_GATSBY_PREVIEW export const inPreviewMode (): boolean inDevelopPreview || inPreviewRunner即满足以下任一条件即视为预览模式NODE_ENVdevelopment且设置ENABLE_GATSBY_REFRESH_ENDPOINT本地调试预览时的/__refresh端点场景RUNNER_TYPE为PREVIEW或INCREMENTAL_PREVIEWSGatsby Cloud 预览运行器设置了IS_GATSBY_PREVIEW。调试方面源码同时支持插件选项debug.preview与环境变量WP_GATSBY_PREVIEW_DEBUG开启后sourcePreviews会用dumper.js打印收到的 webhook body 与待处理动作列表index.tsdebug.printIntrospectionDiff则可在 schema 变化时打印前后差异见 src/steps/declare-plugin-options-schema.js。七、草稿预览的 404 防护虚拟 page-data.json源码中还包含一个易被忽视的细节草稿draft页面在gatsby develop下会因读取page-data.json产生大量 404。为此插件在PREVIEW_SUCCESS回传前会调用writeDummyPageDataJsonIfNeeded对isDraft的预览若public/page-data/path/page-data.json尚不存在则先写入一个仅含{ isDraft: true }的占位文件避免 404 噪音Gatsby 真正生成页面数据后会覆盖该占位文件见 index.ts。八、结语与排查速查整套预览机制的可靠运行依赖「配置正确 页面契约遵守 状态闭环完整」三件事配置侧Gatsby Cloud 启用 CMS Previews、WPGatsby 填好 Preview frontend url 与 webhook、插件url指向正确的/graphql端点、两端插件版本不低于WPGraphQL v0.15.0/WPGatsby v0.6.0契约侧所有需要预览的页面在pageContext中携带节点idACF 场景避开 Gutenberg排查侧预览窗口的错误提示会给出具体修复步骤服务端日志可结合debug.preview与 WP debug log 双重定位常见错误状态包括RECEIVED_PREVIEW_DATA_FROM_WRONG_URLURL 不匹配、NO_PAGE_CREATED_FOR_PREVIEWED_NODE未创建页面或缺失 pageContext.id、GATSBY_PREVIEW_PROCESS_ERROR处理阶段抛错。相关实现与文档可继续在仓库中深入阅读使用文档、预览主流程、onCreatePage 处理、回调清理、预览状态 store、schema 对比。赞分享前端静态站点Web框架【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址https://gitcode.com/gh_mirrors/ga/gatsby点击查看免费下载相关推荐Eclipse Theia 编辑器预览Editor Preview扩展深入解析preview editor 机制、偏好配置与源码原理Eclipse Theia 编辑器预览Editor Preview扩展深入解析preview editor 机制、偏好配置与源码原理 导读 本文围绕 tIDE代码编辑器开发工具前端桌面应用插件系统后端AI 应用用awesome-unity-games学渲染管线URP与HDRP开源示例深度对比指南用awesome unity games学渲染管线URP与HDRP开源示例深度对比指南 想在真实项目中吃透 Unity 渲染管线与其啃枯燥的官方文档不如直前端静态站点Web框架运行 Gatsby 预览服务器Preview Server自建方案与托管方案完整指南运行 Gatsby 预览服务器Preview Server自建方案与托管方案完整指南 在基于 CMS内容管理系统的 Gatsby 站点工作流中最理想前端静态站点Web框架上一篇SSHFS-Win最佳实践清单确保安全、稳定和高效使用的15个要点下一篇Strapi strapi/openapi生成与发布 OpenAPI 规范的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考