When working on Gatsby projects, much of the process relies on gatsby-node.js and the creation of pages through createPages.
Gatsby works great once pages are created, and you can make changes to page content and templates -- but if you need to make any changes to the page creation process, Gatsby doesn't recognize changes in gatsby-node.js and doesn't trigger a hot reload.
When making changes to gatsby-node.js, I have to restart the dev server to see changes. Is there a better way?
System:
OS: macOS High Sierra 10.13.4
CPU: x64 Intel(R) Core(TM) i5-2400S CPU @ 2.50GHz
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 9.8.0 - /usr/local/bin/node
npm: 6.4.0 - /usr/local/bin/npm
Browsers:
Firefox: 61.0.1
npmPackages:
gatsby: next => 2.0.0-rc.13
gatsby-image: next => 2.0.0-rc.1
gatsby-link: next => 2.0.0-rc.2
gatsby-mdx: ^0.1.3 => 0.1.3
gatsby-paginate: 1.0.16 => 1.0.16
gatsby-plugin-feed: next => 2.0.0-rc.2
gatsby-plugin-google-analytics: next => 2.0.0-rc.1
gatsby-plugin-manifest: next => 2.0.2-rc.1
gatsby-plugin-offline: next => 2.0.0-rc.4
gatsby-plugin-react-helmet: next => 3.0.0-rc.1
gatsby-plugin-sharp: next => 2.0.0-rc.3
gatsby-plugin-sitemap: next => 2.0.0-rc.1
gatsby-plugin-twitter: next => 2.0.0-rc.2
gatsby-remark-copy-linked-files: next => 2.0.0-rc.1
gatsby-remark-images: next => 2.0.1-rc.1
gatsby-remark-prismjs: next => 3.0.0-rc.2
gatsby-remark-smartypants: next => 2.0.0-rc.1
gatsby-source-filesystem: next => 2.0.1-rc.1
gatsby-transformer-json: next => 2.1.1-rc.2
gatsby-transformer-react-docgen: next => 2.1.1-rc.5
gatsby-transformer-remark: next => 2.1.1-rc.1
gatsby-transformer-sharp: next => 2.1.1-rc.2
npmGlobalPackages:
gatsby-cli: 1.1.58
gatsby-config.js:
module.exports = {
siteMetadata: {
title: 'Gatsby Documentation Starter',
sidebar: {
pages: [
{
slug: '/about',
title: 'about',
},
],
},
},
plugins: [
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-mdx`,
options: {
defaultLayouts: {
posts: require.resolve('./src/templates/posts.js'),
default: require.resolve('./src/templates/page-default.js'),
},
},
},
`gatsby-plugin-sharp`,
`gatsby-plugin-twitter`,
{
resolve: `gatsby-plugin-feed`,
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `data`,
path: `${__dirname}/content/json`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `components`,
path: `../src/components/`,
},
},
`gatsby-transformer-sharp`,
`gatsby-transformer-json`,
{
resolve: `gatsby-plugin-sitemap`,
options: {
// output: `/some-other-sitemap.xml`,
// exclude: [`/path/to/page`, `/another/page`],
query: `
{
site {
siteMetadata {
siteUrl
}
}
allSitePage {
edges {
node {
path
}
}
}
}`,
},
},
{
resolve: `gatsby-plugin-google-analytics`,
options: {
trackingId: '#',
// Puts tracking script in the head instead of the body
head: false,
// Setting this parameter is optional
anonymize: true,
// Setting this parameter is also optional
respectDNT: true,
},
},
`gatsby-transformer-react-docgen`,
`gatsby-plugin-offline`,
],
}
package.json:
{
"name": "gatsby-starter-default",
"description": "Gatsby default starter",
"version": "1.0.0",
"author": "Kyle Mathews <[email protected]>",
"dependencies": {
"@mdx-js/mdx": "^0.15.0",
"@mdx-js/tag": "^0.15.0",
"gatsby": "next",
"gatsby-image": "next",
"gatsby-link": "next",
"gatsby-mdx": "^0.1.3",
"gatsby-paginate": "1.0.16",
"gatsby-plugin-feed": "next",
"gatsby-plugin-google-analytics": "next",
"gatsby-plugin-manifest": "next",
"gatsby-plugin-offline": "next",
"gatsby-plugin-react-helmet": "next",
"gatsby-plugin-sharp": "next",
"gatsby-plugin-sitemap": "next",
"gatsby-plugin-twitter": "next",
"gatsby-remark-copy-linked-files": "next",
"gatsby-remark-images": "next",
"gatsby-remark-prismjs": "next",
"gatsby-remark-smartypants": "next",
"gatsby-source-filesystem": "next",
"gatsby-transformer-json": "next",
"gatsby-transformer-react-docgen": "next",
"gatsby-transformer-remark": "next",
"gatsby-transformer-sharp": "next",
"markdown-it": "^8.4.2",
"mdx-deck": "^1.7.3",
"prismjs": "^1.15.0",
"react": "^16.4.2",
"react-dom": "^16.4.2",
"react-helmet": "^5.2.0",
"react-jss": "^8.6.1",
"react-markdownit": "^2.5.0"
},
"keywords": [
"gatsby"
],
"license": "MIT",
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write '**/*.js'",
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"prettier": "^1.14.2"
},
"repository": {
"type": "git",
"url": "https://github.com/gatsbyjs/gatsby-starter-default"
}
}
gatsby-node.js:
/**
* Implement Gatsby's Node APIs in this file.
*
* See: https://www.gatsbyjs.org/docs/node-apis/
*/
const path = require('path')
const componentWithMDXScope = require('gatsby-mdx/component-with-mdx-scope')
const queryComponents = (graphql, name) =>
new Promise((resolve, reject) => {
resolve(
graphql(
`
{
componentMetadata(displayName:{ eq: "${name}"}){
displayName
description {
id
}
childrenComponentProp {
id
}
childComponentDescription {
id
}
description {
id
}
methods {
description
docblock
}
props {
id
}
doclets
}
}
`
).then(result => result.data.componentMetadata)
)
})
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
return new Promise((resolve, reject) => {
resolve(
graphql(
`
{
allMdx {
edges {
node {
id
frontmatter {
name
menu
title
}
parent {
... on File {
name
sourceInstanceName
}
}
code {
scope
}
}
}
}
}
`
).then(result => {
if (result.errors) {
console.log(result.errors)
reject(result.errors)
}
// Create blog posts pages.
result.data.allMdx.edges.forEach(async ({ node }) => {
// Query GraphQL for the component docblock data from react-docgen
const componentDocs = await queryComponents(
graphql,
node.frontmatter.name
)
createPage({
path: `/${node.frontmatter.menu.toLowerCase()}/${node.parent.name.toLowerCase()}`,
component: componentWithMDXScope(
path.resolve('./src/templates/posts.js'),
node.code.scope
),
context: {
id: node.id,
name: node.frontmatter.name,
description: componentDocs.description.id,
props: componentDocs.description.id,
childComponentDescription:
componentDocs.childComponentDescription.id,
},
})
})
})
)
})
}
gatsby-browser.js: N/A
gatsby-ssr.js: N/A
@pieh @m-allanson @KyleAMathews any future plans of providing hot-reload for gatsby-node.js?
This would be quite complex to do right now, gatsby-node does a lot more things than just create pages, so we would need to know that only createPages was changed, reload module and run it. This could also cause weird issues if someone store state in gatsby-node context - so for now restarting gatsby develop is your best bet :/
@whoisryosuke We'll be closing this issue, as restarting gatsby develop is the best option
Is this problem confined to pages created in gatsby-node.js or does hot reloading not work for any programmatically created pages? In other words, is it possible to do this another way without resorting to restarting gatesby develop (which in our case takes quite a while).