Gatsby Adapters 完全指南:从部署适配到零配置部署的原理与实践
2026/9/19 3:30:45 网站建设 项目流程

Gatsby Adapters 完全指南:从部署适配到零配置部署的原理与实践

【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby

导读

本文围绕 Gatsby 官方文档 adapters.md 展开,系统讲解 Adapter(适配器)机制:它是什么、解决什么问题、如何查找与使用官方/社区适配器,并结合当前仓库中的 gatsby-adapter-netlify 实现与 Gatsby 核心源码 剖析底层工作流程。读完本文,你将掌握在gatsby-config中接入适配器、理解其自动完成的四类部署准备动作,并了解零配置部署(Zero-Configuration Deployments)背后的自动发现、版本匹配与缓存还原机制。

Adapter 是什么

Adapter(适配器)负责把 Gatsby 的生产构建输出转换成你的部署平台所能理解的形式,从而让 Gatsby 站点可以在任意部署平台上更简单地完成构建与部署。

为什么需要这一层抽象?因为 Gatsby 存在不同的 渲染模式,其中Deferred Static Generation(DSG,延迟静态生成)Server-Side Rendering(SSR,服务端渲染)相比经典的 SSG(静态站点生成)需要更多的部署配置;此外,用户还可以通过 HTTP headers 设置响应头,或通过createRedirectaction 创建 重定向。这些能力在 CDN、无服务器函数等不同平台上落地方式差异很大,Adapter 正是统一承接这些差异的桥梁。

该特性于gatsby@5.12.0加入。

构建期传递的完整信息

在构建期间,Gatsby 会把部署所需的全部信息传递给 Adapter,使其能针对特定平台准备输出。一个 Adapter 会自动执行以下动作:

  • 为静态资源应用 HTTP headers
  • 应用重定向(redirects)与重写(rewrites)。Adapter 在必要时也可以创建自己的重定向或重写,例如把 serverless functions 映射到内部 URL
  • 将 Gatsby 产出的 serverless functions 用平台特定代码包装(如有必要)。Gatsby 会产出Express 风格(Express-like)的 handler
  • 为 URL 应用 trailing slash 行为与 path prefix(路径前缀)
  • 可能还会把资源上传到 CDN

源码层面的佐证

从 manager.ts 可以看到,Gatsby 在构建早期调用manager.config()获取适配器配置并派发SET_ADAPTERaction;如果 Adapter 报告不支持某些特性(如pathPrefixfalse,或用户配置的trailingSlash不在支持列表中),Gatsby 会通过reporter.warn提示"不兼容",同时通过DISABLE_PLUGINS_BY_NAMEaction 禁用与 Adapter 职责冲突的插件(例如 Netlify 适配器会禁用gatsby-plugin-netlifygatsby-plugin-netlify-cache,见 index.ts)。

查找 Adapter

目前官方提供的适配器:

  • gatsby-adapter-netlify—— 面向 Netlify 的官方适配器,源码位于仓库 packages/gatsby-adapter-netlify

要查找更多社区适配器,可以在 npm 上搜索gatsby-adapter前缀:gatsby-adapter-。如果找不到你所在平台的适配器,可以参考 创建 Adapter 指南 自行实现一个。

使用 Adapter

使用方式很简单:在gatsby-config中通过adapter选项接入。

基础用法:

const adapter = require("gatsby-adapter-foo") module.exports = { adapter: adapter() }

如果 Adapter 接受自定义选项,可以这样传入:

const adapter = require("gatsby-adapter-foo") module.exports = { adapter: adapter({ // Adapter options }) }

注意:Adapter 导出的是一个工厂函数AdapterInit),调用后返回 Adapter 实例对象,所以adapter选项的值是adapter(...)的调用结果,而不是模块本身。

真实案例:gatsby-adapter-netlify 的用法

以仓库中的官方适配器为例(见 README.md),安装并配置:

npm install gatsby-adapter-netlify
const adapter = require("gatsby-adapter-netlify").default module.exports = { adapter: adapter({ excludeDatastoreFromEngineFunction: false, imageCDN: false, }), }

该适配器在 Netlify 上启用的能力包括:重定向、HTTP headers、默认缓存头应用、DSG、SSR、Gatsby Functions、跨部署的构建缓存,以及(可选配置的)Gatsby Image/File CDN。

官方适配器的两个关键选项

excludeDatastoreFromEngineFunction(可选,默认false

设为true时,Gatsby 不会把 LMDB 数据存储打进用于 SSR/DSG 的 serverless functions,而是将 datastore 上传到 Netlify 的 CDN,在函数首次加载时下载。可以通过GATSBY_EXCLUDE_DATASTORE_FROM_BUNDLE=true环境变量开启(对零配置部署场景很有用)。

从源码看,index.ts 的confighook 会优先读取配置项,其次读取GATSBY_EXCLUDE_DATASTORE_FROM_BUNDLE环境变量;如果设置为true但拿不到deployURL(本地环境没有DEPLOY_URL),会降级为false并输出警告。

imageCDN(可选,默认false

设为true时,图像不再在构建期下载和处理,而是延迟到请求期交由 Netlify Image CDN 处理,能大幅缩短使用远程图片(如 CMS 站点)的构建时间。同样可通过NETLIFY_IMAGE_CDN=true环境变量开启。

开启后需要在netlify.toml中额外配置允许的远程图片域名(Remote Path)。不同的 source 插件对应不同的正则模式,以下是官方 README 给出的示例:

  • gatsby-source-contentful

    [images] remote_images = [ # <your-contentful-space-id> 对应 gatsby-config 中 # gatsby-source-contentful 插件的 spaceId 选项 "https://images.ctfassets.net/<your-contentful-space-id>/.*" ]
  • gatsby-source-drupal

    [images] remote_images = [ # <your-drupal-base-url> 对应 gatsby-config 中 # gatsby-source-drupal 插件的 baseUrl 选项 "<your-drupal-base-url>/.*" ]
  • gatsby-source-wordpress

    [images] remote_images = [ # <your-wordpress-url> 对应 gatsby-config 中 # gatsby-source-wordpress 插件的 url 选项 # 这里不需要包含 /graphql 路径 "<your-wordpress-url>/.*" ]

如果使用了较新版本的 Contentful、Drupal 或 WordPress source 插件,Gatsby 与 Netlify Adapter 会自动检测缺失的 Remote Path 模式并给出警告及所需的配置模式。

从源码理解配置如何被消费

在 index.ts 的adapthook 中可以看到实际工作流:

  1. 若启用imageCDN,先调用handleAllowedRemoteUrlsNetlifyConfig校验remoteFileAllowedUrls,再通过prepareFileCdnHandler生成 File CDN 处理器;
  2. handleRoutesManifest(routesManifest, headerRoutes)把 Gatsby 的路由清单(静态路由、函数路由、重定向路由)翻译成 Netlify 的_redirects/_headers配置——route-handler.ts 中用# gatsby-adapter-netlify start/end标记注入内容,并兼容旧插件@netlify/plugin-gatsbygatsby-plugin-netlify的遗留标记;
  3. 遍历functionsManifest,通过prepareFunctionVariants为每个函数准备平台特定代码。

Adapter 的核心 API 与底层原理

理解 Adapter 的接口,有助于你评估现有适配器能力,也是(如需)自行创建适配器的基础。完整类型定义见 types.ts。

Adapter 实例结构

Adapter 工厂函数返回的对象包含以下键:

  • name:适配器的唯一名称,遵循gatsby-adapter-<name>@scope/gatsby-adapter-<name>命名规范
  • cache(可选):两个钩子都接收directories(需要缓存/还原的构建目录)和reporter实例
    • restore:从历史构建还原目录,在构建流程很早阶段执行;返回false时 Gatsby 会跳过缓存还原
    • store:存储当前构建的目录,在构建流程最后阶段之一执行
  • adapt:把 Gatsby 输出转换为平台可部署形式,同样在构建末期执行
  • config(可选):把 Adapter 的信息回传给 Gatsby,使其调整构建流程

以 Netlify 适配器为例,index.ts 的cache.restore/cache.store在 Netlify 构建环境(/opt/build/cache)或本地环境(.netlify/build-cache)下使用@netlify/cache-utils还原/保存.cachepublic目录,从而实现跨部署的构建缓存。

adapt 钩子的输入

adapt接收以下输入(类型见 types.ts):

  • routesManifest:对象数组,包含staticfunctionredirect三种类型路由。静态路由会带有默认 headers(用户可通过 HTTP headers 选项在gatsby-config中扩展或覆盖);路由路径还会应用 trailingSlash 选项
  • functionsManifest:对象数组,包含每个函数的入口文件路径与所需文件列表
  • pathPrefixgatsby-config中 pathPrefix 选项的值
  • trailingSlashgatsby-config中 trailingSlash 选项的值
  • remoteFileAllowedUrls:允许的远程文件 URL 数组(由 source 插件通过addRemoteFileAllowedUrlaction 提供),用于 Gatsby Image/File CDN;该字段于gatsby@5.13.0加入

从 manager.ts 的getRoutesManifest可以看出清单的生成细节:SSG 页面生成static路由(HTML 与 page-data JSON),DSG/SSR 页面生成function路由(functionIdssr-engine,DSG 会标记cache: true);createRedirect产生的重定向生成redirect路由(状态码取statusCode或按isPermanent取 301/302);路径统一处理 path prefix 与 trailing slash(重定向路由除外),并按rankRoute打分排序以保证确定性顺序。

config 钩子的输出

config钩子返回以下键(类型见 types.ts):

  • deployURL(可选):单次部署的唯一 URL
  • excludeDatastoreFromEngineFunction(可选):为true时 Gatsby 不把 LMDB datastore 打进 SSR/DSG 用的 serverless functions,而是放入public目录,后续从deployURL下载
  • supports(可选):描述适配器支持的特性
    • pathPrefix:为false时,若用户使用 pathPrefix 则构建失败
    • trailingSlash:提供支持的 trailingSlash 选项数组,例如['always']
  • pluginsToDisable(可选):使用该适配器时应被禁用的插件名数组,用于避免与 Adapter 职责重复的插件冲突
  • imageCDNUrlGeneratorModulePath(可选,gatsby@5.13.0加入):指向 CommonJS 模块的绝对路径,该模块导出符合ImageCdnUrlGeneratorFn类型的函数,用于生成图片 CDN URL,可将IMAGE_CDN作业从构建期转移到请求期,降低构建时间
  • fileCDNUrlGeneratorModulePath(可选,gatsby@5.13.0加入):类似地导出FileCdnUrlGeneratorFn类型的函数,用于生成文件 CDN URL

在 manager.ts 中,Gatsby 校验了excludeDatastoreFromEngineFunction必须有deployURL支撑,否则抛错;同时把imageCDNUrlGeneratorModulePath/fileCDNUrlGeneratorModulePath写入global.__GATSBY供后续处理。

Netlify 适配器的config返回值(index.ts)展示了这些字段的完整用法:

return { excludeDatastoreFromEngineFunction, deployURL, // 本地为 http://localhost:8888,否则取 DEPLOY_URL supports: { pathPrefix: true, trailingSlash: [`always`, `never`, `ignore`], }, pluginsToDisable: [ `gatsby-plugin-netlify-cache`, `gatsby-plugin-netlify`, ], imageCDNUrlGeneratorModulePath: useNetlifyImageCDN ? require.resolve(`./image-cdn-url-generator`) : undefined, fileCDNUrlGeneratorModulePath: useNetlifyImageCDN ? require.resolve(`./file-cdn-url-generator`) : undefined, functionsPlatform: `linux`, functionsArch: `x64`, }

零配置部署(Zero-Configuration Deployments)原理

零配置部署文档 指出:零配置部署由 Adapter 驱动。当你部署到受支持的平台时,Gatsby 会自动安装并使用正确的 Adapter,无需任何手动配置(同样自gatsby@5.12.0起可用)。

适配器清单与自动发现

零配置部署由 adapters.js 清单文件控制。当前清单只包含 Netlify 一项:

const adaptersManifest = [ { name: `Netlify`, module: `gatsby-adapter-netlify`, test: () => !!process.env.NETLIFY || !!process.env.NETLIFY_LOCAL, versions: [ { gatsbyVersion: `^5.12.10`, moduleVersion: `^1.2.1` }, { gatsbyVersion: `>=5.0.0 <5.12.10`, moduleVersion: `>=1.0.0 <=1.0.3` }, ], }, ]

清单条目的关键字段(类型见 types.ts):test()函数判断当前环境是否应使用该适配器;versions数组把 Gatsby 版本范围映射到对应的适配器版本范围——这在 API 变更或修复需要不同实现时非常有用。

自动安装的完整流程

init.ts 实现了适配器的发现与安装逻辑:

  1. 拉取最新的 adapters manifest(失败则回退到当前 Gatsby 版本内置的 manifest)
  2. 找出第一个test()返回true的候选适配器
  3. 依据当前 Gatsby 版本从versions中选出匹配的适配器版本
  4. 优先尝试加载用户手动安装的适配器;版本不兼容则警告并忽略
  5. 检查之前是否已在.cache/adapters安装过兼容版本
  6. 若都未命中,则在.cache/adapters中执行npm install <module>@<version>自动安装(带--legacy-peer-deps --save-exact等参数)
  7. 安装后再次加载并提示:如果打算长期留在该平台,建议把适配器显式加入dependencies以获得更快更稳的安装

如果自动安装或加载失败,默认会通过reporter.panic终止构建以避免产生损坏的部署;设置GATSBY_CONTINUE_BUILD_ON_ADAPTER_MISMATCH=true环境变量可以跳过此检查继续构建(不使用任何适配器)。

在 manager.ts 中,如果用户在gatsby-config里显式配置了adapter,则优先使用用户配置,跳过零配置自动发现。

手动安装适配器的建议

如果打算长期使用某个部署平台,建议把适配器加入dependencies,以获得更快、更稳健的安装。如果需要修改适配器的任何选项值,则必须手动安装适配器到dependencies才能更改配置。

为清单贡献新适配器

如果你按 创建 Adapter 指南 实现了适配器并希望加入官方清单,可以为 adapters.js 提交 PR。需要注意的是:欢迎所有 PR,但不保证所有适配器都会进入官方清单,Gatsby 团队会审查并给出反馈。

扩展阅读:创建、测试与发布自己的 Adapter

最小可运行骨架

如需在本地快速原型一个适配器,可以在项目根目录直接创建gatsby-adapter-foo.js

const createAdapterFoo = adapterOptions => { return { name: `gatsby-adapter-foo`, // cache hooks... adapt({ routesManifest, functionsManifest, pathPrefix, trailingSlash, reporter }) { // Adapt implementation reporter.info('gatsby-adapter-foo is working') }, } } module.exports = createAdapterFoo

然后在gatsby-config中引用:

const adapter = require("./gatsby-adapter-foo") module.exports = { adapter: adapter() }

测试与发布

官方建议使用 Jest/Vitest 做单元测试、Cypress/Playwright 做端到端测试(可参考仓库中的 e2e-tests/adapters 完整测试套件)。发布到 npm 前建议核对清单:命名遵循gatsby-adapter-<name>@scope/gatsby-adapter-<name>package.jsonversion设为1.0.0起步并遵循 semver;keywords包含gatsbygatsby-plugingatsby-adapter以便在插件库中被检索;peerDependencies声明兼容的gatsby版本范围(例如"gatsby": "^5.0.0",多主版本支持可写"^5.0.0 || ^6.0.0");build脚本把源码编译为 CJS 到dist目录并配置main/files;增加prepare脚本(如"prepare": "npm run clean && npm run build")确保发布前产物干净。

总结

Adapter 机制把"平台差异"从 Gatsby 核心构建流程中剥离:构建期 Gatsby 通过 manager.ts 生成 routes/functions 两个 manifest 并携带 headers、trailing slash、path prefix 等信息,交给 Adapter 的adapt钩子翻译成平台配置;config钩子反向把平台能力(如deployURL、特性支持范围)回传给 Gatsby 以调整构建;cache钩子则负责跨部署的构建缓存。配合 adapters.js 清单与 init.ts 的自动发现/安装逻辑,就构成了从gatsby@5.12.0开始的零配置部署体验。对开发者而言,在gatsby-config中设置adapter: adapter(options)即可接入;找不到现成适配器时,也可参照 创建 Adapter 指南 与类型定义 types.ts 自行实现并发布。

【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询