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。有关更多信息,请参阅 调试异步生命周期。
如果您的插件不执行异步操作,您可以直接返回。
API
动态创建页面。此扩展点仅在初始节点源化和转换以及 GraphQL schema 创建完成后调用,因此您可以使用您的数据来创建页面。
您还可以从远程或本地源获取数据来创建页面。
另请参阅 `createPage` 操作的文档。
参数
- 解构对象
有关更多详细信息,请参阅 `Node API Helpers` 的文档。
graphqlfunction: 查询 GraphQL API。在此处的示例中查看。
reporterGatsbyReporter记录问题。有关更多详细信息,请参阅 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。
参数
- 解构对象
intermediateSchemaGraphQLSchema当前 GraphQL schema
createResolversfunction为 GraphQL 字段配置添加自定义解析器。
$1objectresolversobjectGraphQL 类型名称到自定义解析器函数的对象映射
optionsobject可选的 `createResolvers` 选项
ignoreNonexistentTypesobject在尝试为不存在的类型添加解析器时,会抑制警告。这对于可选的扩展非常有用。
示例
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。
参数
- 解构对象
actionsobjectcreateTypesobjectcreateFieldExtensionobjectaddThirdPartySchemaobject
示例
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 配置。
参数
- 解构对象
stagestring当前构建阶段。可以是 'develop'、'develop-html'、'build-javascript' 或 'build-html' 之一。
actionsobject
optionsobjectBabel 配置
示例
exports.onCreateBabelConfig = ({ actions }) => {
actions.setBabelPlugin({
name: `babel-plugin-that-i-like`,
options: {}
})
}在启动 `gatsby develop` 服务器时运行。可用于向服务器添加代理和 Express 中间件。
参数
- 解构对象
appExpress用于运行开发服务器的 Express 应用。
示例
exports.onCreateDevServer = ({ app }) => {
app.get('/hello', function (req, res) {
res.send('hello world')
})
}创建新页面时调用。此扩展 API 可用于以编程方式修改由其他插件创建的页面,例如如果您想要不带尾部斜杠的路径。
Gatsby 有一种机制可以防止对同一 `gatsby-node.js` 创建的页面调用 `onCreatePage`,以避免无限循环/回调。
有关此 API 的更多信息,请参阅 创建和修改页面指南。
源码
允许插件扩展/修改网站的 webpack 配置。此方法可由任何 Gatsby 网站、应用程序或插件使用,不仅仅是插件。
另请参阅 `setWebpackConfig` 的文档。
参数
- 解构对象
stagestring当前构建阶段。可以是 'develop'、'develop-html'、'build-javascript' 或 'build-html' 之一。
getConfigfunction返回当前 webpack 配置。
rulesobject一组预配置的 webpack 配置规则。
loadersobject一组预配置的 webpack 配置加载器。
pluginsobject一组预配置的 webpack 配置插件。
actionsobject
示例
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 准备之前。
参数
- 解构对象
actionsobject
示例
exports.onPreInit = ({ actions }) => {
}在 bootstrap 阶段运行。插件可以使用此 API 来定义其选项的 schema,使用 Joi 来验证用户传递给插件的选项。
参数
- 解构对象
JoiJoi用于定义 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 字段。
参数
- 解构对象
typeobject包含 `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)
}