Using the onCreateNode API works great. However, on subsequent builds (e.g. with a .cache folder persisted), the nodes created from that API do not seem to be cached correctly or otherwise persist, and thus the build breaks.
In particular, check out the gatsby-node.js file, where I create a custom node based on the contents of a JS file.
Following steps serve to reproduce:
yarn (or npm install) to install depsyarn build and notice that it passesyarn build again, and notice the bellow failure:error GraphQL Error Unknown field `allExampleCode` on type `Query`
file: /Users/dschau/Code/Work/gatsby/test/on-create-node-repro/src/pages/index.js
1 |
2 | query {
3 | site {
4 | siteMetadata {
5 | title
6 | description
7 | }
8 | }
9 |
> 10 | examples:allExampleCode {
| ^
11 | edges {
12 | node {
13 | code
14 | mdAbsolutePath
15 | }
16 | }
17 | }
18 | markdown:allMarkdownRemark {
19 | edges {
20 | node {
Build should reliably pass and cache custom node types _or_ they should be created each time (preferably the former).
Builds do not reliably pass.
System:
OS: macOS 10.14
CPU: x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
Shell: 5.3 - /bin/zsh
Binaries:
Node: 10.11.0 - /usr/local/bin/node
Yarn: 1.10.1 - /usr/local/bin/yarn
npm: 6.4.1 - /usr/local/bin/npm
Browsers:
Chrome: 69.0.3497.100
Firefox: 62.0.2
Safari: 12.0
npmPackages:
gatsby: ^2.0.0 => 2.0.12
gatsby-plugin-feed: ^2.0.5 => 2.0.5
gatsby-plugin-google-analytics: ^2.0.5 => 2.0.6
gatsby-plugin-manifest: ^2.0.2 => 2.0.4
gatsby-plugin-offline: ^2.0.5 => 2.0.5
gatsby-plugin-react-helmet: ^3.0.0 => 3.0.0
gatsby-plugin-sharp: ^2.0.5 => 2.0.5
gatsby-plugin-typography: ^2.2.0 => 2.2.0
gatsby-remark-copy-linked-files: ^2.0.5 => 2.0.5
gatsby-remark-images: ^2.0.1 => 2.0.3
gatsby-remark-prismjs: ^3.0.0 => 3.0.1
gatsby-remark-responsive-iframe: ^2.0.5 => 2.0.5
gatsby-remark-smartypants: ^2.0.5 => 2.0.5
gatsby-source-filesystem: ^2.0.1 => 2.0.1
gatsby-transformer-remark: ^2.1.1 => 2.1.4
gatsby-transformer-sharp: ^2.1.1 => 2.1.3
npmGlobalPackages:
gatsby-dev-cli: 2.4.3
gatsby: 2.0.0
For posterity, the issue is that nodes are garbage collected based on the existence of a parent (thanks @KyleAMathews)
So the fix is do something like this (at the plugin level):
createNode({
id: name,
children: [],
parent: node.id,
code,
mdAbsolutePath: absolutePath.replace(/\.js$/, '.md'),
internal: {
type: 'ExampleCode',
contentDigest: createContentDigest(JSON.stringify(code)),
},
});
instead of
createNode({
id: name,
children: [],
parent: `SOME_PARENT_STR`,
code,
mdAbsolutePath: absolutePath.replace(/\.js$/, '.md'),
internal: {
type: 'ExampleCode',
contentDigest: createContentDigest(JSON.stringify(code)),
},
});
We probably could show warning if createNode is used in onCreateNode and it doesn't set passed node as parent?
Most helpful comment
We probably could show warning if
createNodeis used inonCreateNodeand it doesn't set passednodeas parent?