立即迁移到 Netlify

Netlify 宣布 Gatsby Cloud 的下一次迭代。 了解更多

Gatsby Node API

简介

Gatsby 为插件和网站构建者提供了许多用于构建网站的 API。`gatsby-node.js` / `gatsby-node.ts` 文件中的代码会在构建网站的过程中运行一次。您可以使用其 API 动态创建页面,将数据添加到 GraphQL,或响应构建生命周期中的事件。要使用 Gatsby Node API,请在网站根目录创建一个名为 `gatsby-node.js` / `gatsby-node.ts` 的文件。在此文件中导出您希望使用的任何 API。

您可以使用 JavaScript(CommonJS 或 ES Modules (ESM) 语法)或 TypeScript 来编写文件。

每个 Gatsby Node API 都会接收一组助手函数。这些函数允许您访问诸如报告等多种方法,或执行诸如创建新页面等操作。

一个实现两个 API(`onPostBuild` 和 `createPages`)的 `gatsby-node.js` 文件示例。

有关如何在 TypeScript 中设置 `gatsby-node` 文件的信息,请参阅 TypeScript 和 Gatsby 文档

如果您不想使用 CommonJS 语法,请阅读 ES Modules (ESM) 和 Gatsby 文档

异步与同步操作

如果您的插件执行异步操作(磁盘 I/O、数据库访问、调用远程 API 等),您必须返回一个 Promise(显式使用 `Promise` API 或隐式使用 `async`/`await` 语法)或使用传递给第 3 个参数的回调函数。Gatsby 需要知道插件何时完成,因为某些 API 为了正确工作需要先完成之前的 API。有关更多信息,请参阅 调试异步生命周期

如果您的插件不执行异步操作,您可以直接返回。

立即开始构建,在 Netlify!

API

动态创建页面。此扩展点仅在初始节点源化和转换以及 GraphQL schema 创建完成后调用,因此您可以使用您的数据来创建页面。

您还可以从远程或本地源获取数据来创建页面。

另请参阅 `createPage` 操作的文档

参数

  • 解构对象

    有关更多详细信息,请参阅 `Node API Helpers` 的文档

    • actions Actions
      • createPage function
    • graphql function

      : 查询 GraphQL API。在此处的示例中查看。

    • reporter GatsbyReporter

      记录问题。有关更多详细信息,请参阅 GatsbyReporter 文档

返回值

Promise<void>

不需要返回值,但调用者将 `await` 任何返回的 Promise。

示例

const path = require(`path`)

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  const blogPostTemplate = path.resolve(`src/templates/blog-post.js`)
  // Query for markdown nodes to use in creating pages.
  // You can query for whatever data you want to create pages for e.g.
  // products, portfolio items, landing pages, etc.
  // Variables can be added as the second function parameter
  return graphql(`
    query loadPagesQuery ($limit: Int!) {
      allMarkdownRemark(limit: $limit) {
        edges {
          node {
            frontmatter {
              slug
            }
          }
        }
      }
    }
  `, { limit: 1000 }).then(result => {
    if (result.errors) {
      throw result.errors
    }

    // Create blog post pages.
    result.data.allMarkdownRemark.edges.forEach(edge => {
      createPage({
        // Path for this page — required
        path: `${edge.node.frontmatter.slug}`,
        component: blogPostTemplate,
        context: {
          // Add optional context data to be inserted
          // as props into the page component.
          //
          // The context data can also be used as
          // arguments to the page GraphQL query.
          //
          // The page "path" is always available as a GraphQL
          // argument.
        },
      })
    })
  })
}

类似于 `createPages`,但适用于希望自己管理页面创建和删除的插件,以响应由 Gatsby *不*管理的那些数据中的更改。实现 `createPages` 的插件将定期被调用以在 Gatsby 的数据发生变化时重新计算页面信息,而实现 `createPagesStatefully` 的插件则不会。

一个使用此扩展点的插件示例是 `gatsby-plugin-page-creator` 插件,它监视 `src/pages` 目录中 JS 页面的添加和删除。由于 `pages` 目录中的文件是它的真相来源,Gatsby 并不知晓,它需要维护自己的状态以了解何时添加和删除页面。


源码

向 GraphQL schema 添加自定义字段解析器。

通过提供字段配置或为现有字段添加解析器函数来允许添加新字段。

注意事项

  • 不允许覆盖字段类型,而是使用 `createTypes` 操作。对于从第三方 schema 添加的类型,如果无法做到这一点,则允许覆盖字段类型。
  • 新字段将不会在 `filter` 和 `sort` 输入类型上可用。如果需要此功能,请扩展使用 `createTypes` 定义的类型。
  • 在字段配置中,类型可以被引用为字符串。
  • 当使用现有字段解析器扩展字段时,原始解析器函数可以从 `info.originalResolver` 中获得。
  • `createResolvers` API 在 schema 生成的最后一步调用。因此,中间 schema 可通过 `intermediateSchema` 属性获得。在解析器函数本身中,建议从 `info.schema` 访问最终构建的 schema。
  • Gatsby 的数据层,包括所有内部查询功能,都公开在 context.nodeModel 上。节点存储可以直接使用 `findOne`、`getNodeById` 和 `getNodesByIds` 进行查询,而更复杂的查询可以使用 `findAll` 进行组合。
  • 可以向根 `Query` 类型添加字段。
  • 当使用第一个解析器参数(示例如下中的 `source`,通常也称为 `parent` 或 `root`)时,请注意字段解析器在查询中可能会被调用多次,例如当字段同时存在于输入过滤器和选择集中时。这意味着 `source` 上的外键字段可能已被解析或未被解析。

有关更完整的示例,请参阅 using-type-definitions

参数

  • 解构对象
    • intermediateSchema GraphQLSchema

      当前 GraphQL schema

    • createResolvers function

      为 GraphQL 字段配置添加自定义解析器。

  • $1 object
    • resolvers object

      GraphQL 类型名称到自定义解析器函数的对象映射

    • options object

      可选的 `createResolvers` 选项

      • ignoreNonexistentTypes object

        在尝试为不存在的类型添加解析器时,会抑制警告。这对于可选的扩展非常有用。

示例

exports.createResolvers = ({ createResolvers }) => {
  const resolvers = {
    Author: {
      fullName: {
        resolve: (source, args, context, info) => {
          return source.firstName + source.lastName
        }
      },
    },
    Query: {
      allRecentPosts: {
        type: [`BlogPost`],
        resolve: async (source, args, context, info) => {
          const { entries } = await context.nodeModel.findAll({ type: `BlogPost` })
          return entries.filter(
            post => post.publishedAt > Date.UTC(2018, 0, 1)
          )
        }
      }
    }
  }
  createResolvers(resolvers)
}

通过创建类型定义、字段扩展或添加第三方 schema 来自定义 Gatsby 的 GraphQL schema。

此 API 中仅提供 `createTypes`、`createFieldExtension` 和 `addThirdPartySchema` 操作。有关其用法的详细信息,请参阅操作文档。

此 API 在 schema 生成之前立即运行。对于已生成 schema 的修改,例如自定义添加的第三方类型,请使用 `createResolvers` API。

参数

  • 解构对象
    • actions object
      • createTypes object
      • createFieldExtension object
      • addThirdPartySchema object

示例

exports.createSchemaCustomization = ({ actions }) => {
  const { createTypes, createFieldExtension } = actions

  createFieldExtension({
    name: 'shout',
    extend: () => ({
      resolve(source, args, context, info) {
        return String(source[info.fieldName]).toUpperCase()
      }
    })
  })

  const typeDefs = `
    type MarkdownRemark implements Node @dontInfer {
      frontmatter: Frontmatter
    }
    type Frontmatter {
      title: String!
      tagline: String @shout
      date: Date @dateformat
      image: File @fileByRelativePath
    }
  `
  createTypes(typeDefs)
}

允许插件通过调用 `setBabelPlugin` 或 `setBabelPreset` 来扩展/修改网站的 Babel 配置。

参数

  • 解构对象
    • stage string

      当前构建阶段。可以是 'develop'、'develop-html'、'build-javascript' 或 'build-html' 之一。

    • actions object
  • options object

    Babel 配置

示例

exports.onCreateBabelConfig = ({ actions }) => {
  actions.setBabelPlugin({
    name: `babel-plugin-that-i-like`,
    options: {}
  })
}

在启动 `gatsby develop` 服务器时运行。可用于向服务器添加代理和 Express 中间件。

参数

  • 解构对象

示例

exports.onCreateDevServer = ({ app }) => {
  app.get('/hello', function (req, res) {
    res.send('hello world')
  })
}

源码

当创建新节点时调用。希望扩展或转换其他插件创建的节点的插件应实现此 API。

另请参阅 `createNode` 和 `createNodeField` 的文档。

创建源插件》教程演示了插件或网站如何使用此 API。

示例

exports.onCreateNode = ({ node, actions }) => {
  const { createNode, createNodeField } = actions
  // Transform the new node here and create a new node or
  // create a new node field.
}

创建新页面时调用。此扩展 API 可用于以编程方式修改由其他插件创建的页面,例如如果您想要不带尾部斜杠的路径。

Gatsby 有一种机制可以防止对同一 `gatsby-node.js` 创建的页面调用 `onCreatePage`,以避免无限循环/回调。

有关此 API 的更多信息,请参阅 创建和修改页面指南。


源码

允许插件扩展/修改网站的 webpack 配置。此方法可由任何 Gatsby 网站、应用程序或插件使用,不仅仅是插件。

另请参阅 `setWebpackConfig` 的文档。

参数

  • 解构对象
    • stage string

      当前构建阶段。可以是 'develop'、'develop-html'、'build-javascript' 或 'build-html' 之一。

    • getConfig function

      返回当前 webpack 配置。

    • rules object

      一组预配置的 webpack 配置规则。

    • loaders object

      一组预配置的 webpack 配置加载器。

    • plugins object

      一组预配置的 webpack 配置插件。

    • actions object

示例

exports.onCreateWebpackConfig = ({
 stage, getConfig, rules, loaders, actions
}) => {
  actions.setWebpackConfig({
    module: {
      rules: [
        {
          test: 'my-css',
          use: [loaders.style(), loaders.css()]
        },
      ],
    },
  });
}

在每个进程中执行的生命周期(每个进程一次)。用于存储操作等以供将来使用。

示例

let createJobV2
exports.onPluginInit = ({ actions }) => {
  // store job creation action to use it later
  createJobV2 = actions.createJobV2
}

在所有其他扩展 API 被调用后,在 bootstrap 过程结束时调用。


在构建过程的所有其他部分完成后调用的最后一个扩展点。

示例

exports.onPostBuild = ({ reporter, basePath, pathPrefix }) => {
 reporter.info(
  `Site was built with basePath: ${basePath} & pathPrefix: ${pathPrefix}`
 );
};

当 Gatsby 完成初始化并准备好引导您的网站时调用。


在构建过程中调用的第一个扩展点。在 bootstrap 完成后、构建步骤开始之前调用。


在从 JavaScript 文件提取 GraphQL 查询/片段之前运行。对于插件添加更多具有查询/片段的 JavaScript 文件(例如从 `node_modules`)非常有用。

请参阅 `gatsby-transformer-sharp` 和 `gatsby-source-contentful` 获取示例。


Gatsby 执行期间调用的第一个 API,在插件加载后立即运行,在缓存初始化和 bootstrap 准备之前。

参数

  • 解构对象
    • actions object

示例

exports.onPreInit = ({ actions }) => {

}

在 bootstrap 阶段运行。插件可以使用此 API 来定义其选项的 schema,使用 Joi 来验证用户传递给插件的选项。

参数

  • 解构对象
    • Joi Joi

      用于定义 schema 的 `Joi` 实例。

示例

exports.pluginOptionsSchema = ({ Joi }) => {
  return Joi.object({
    // Validate that the anonymize option is defined by the user and is a boolean
    anonymize: Joi.boolean().required(),
  })
}

要求编译到 JavaScript 的插件处理源文件,以便查询运行程序可以提取 GraphQL 查询以供执行。


让实现其他编译到 JavaScript 的插件支持的插件添加到“可解析”文件扩展名的列表中。Gatsby 默认支持 `.js` 和 `.jsx`。

返回值

string[]

扩展名数组。


源码

在 GraphQL schema 创建期间调用。允许插件向从数据节点创建的类型添加新字段。它将为每种类型单独调用。

此函数应返回一个形状为 GraphQLFieldConfigMap 的对象,该对象将附加到 Gatsby 从数据节点推断出的字段。

注意:从 `gatsby/graphql` 导入 GraphQL 类型,并且不要将 `graphql` 包添加到您的项目/插件依赖项中,以避免出现“Schema must contain unique named types but contains multiple types named”错误。`gatsby/graphql` 导出了所有内置 GraphQL 类型以及 `GraphQLJSON` 类型。

许多转换器插件使用此 API 添加带参数的字段。

添加一个“excerpt”字段,用户在编写查询时可以指定要从 markdown 源截断的字符数。

许多图像转换选项作为 GraphQL 字段。

参数

  • 解构对象
    • type object

      包含 `name` 和 `nodes` 的对象。

示例

import { GraphQLString } from "gatsby/graphql"

exports.setFieldsOnGraphQLNodeType = ({ type }) => {
  if (type.name === `File`) {
    return {
      newField: {
        type: GraphQLString,
        args: {
          myArgument: {
            type: GraphQLString,
          }
        },
        resolve: (source, fieldArgs) => {
          return `Id of this node is ${source.id}.
                  Field was called with argument: ${fieldArgs.myArgument}`
        }
      }
    }
  }

  // by default return empty object
  return {}
}

在为插件调度 `onCreateNode` 回调之前调用。如果返回假值,Gatsby 将不会为此插件的该节点调度 `onCreateNode` 回调。注意:此 API 不接收其他回调获取的常规 `api` 作为第一个参数。

示例

exports.shouldOnCreateNode = ({node}, pluginOptions) => node.internal.type === 'Image'

告诉插件源化节点的扩展点。此 API 在 Gatsby bootstrap 序列中调用。源插件使用此钩子来创建节点。此 API 每个插件调用一次(并且为您的网站的 `gatsby-config.js` 文件调用一次)。如果您在 `gatsby-node.js` 中定义此钩子,它将在您的所有源插件完成节点创建后调用一次。

创建源插件》教程演示了插件或网站如何使用此 API。

另请参阅 `createNode` 的文档。

示例

exports.sourceNodes = ({ actions, createNodeId, createContentDigest }) => {
  const { createNode } = actions

  // Data can come from anywhere, but for now create it manually
  const myData = {
    key: 123,
    foo: `The foo field of my node`,
    bar: `Baz`
  }

  const nodeContent = JSON.stringify(myData)

  const nodeMeta = {
    id: createNodeId(`my-data-${myData.key}`),
    parent: null,
    children: [],
    internal: {
      type: `MyNodeType`,
      mediaType: `text/html`,
      content: nodeContent,
      contentDigest: createContentDigest(myData)
    }
  }

  const node = Object.assign({}, myData, nodeMeta)
  createNode(node)
}
在 GitHub 上编辑此页面
©2025Gatsby, Inc.