gatsby: [v2] gatsbyNode[api] is not a function

Description

Getting a TypeError: gatsbyNode[api] is not a function error when trying to start up after migration to Gatsby v2.

To get started, we ran through the documentation and whatever debugging we could figure out via the issues: https://next.gatsbyjs.org/docs/migrating-from-v1-to-v2/

Please let me know if I missed anything below. Thanks in advance

Steps to reproduce

gatsby develop

Expected result

Site should compile

Actual result

TypeError: gatsbyNode[api] is not a function
- api-runner-node.js:104 runAPI
  [website]/[gatsby]/dist/utils/api-runner-node.js:104:37
- api-runner-node.js:173 mapSeries
  [website]/[gatsby]/dist/utils/api-runner-node.js:173:25
- map.js:27
  [website]/[async]/internal/map.js:27:9
- eachOfLimit.js:66 replenish
  [website]/[async]/internal/eachOfLimit.js:66:17
- eachOfLimit.js:50 iterateeCallback
  [website]/[async]/internal/eachOfLimit.js:50:17
- onlyOnce.js:12
  [website]/[async]/internal/onlyOnce.js:12:16
- map.js:29
  [website]/[async]/internal/map.js:29:13
- util.js:16 tryCatcher
  [website]/[bluebird]/js/release/util.js:16:23
- nodeify.js:23 Promise.successAdapter
  [website]/[bluebird]/js/release/nodeify.js:23:30
- promise.js:566 Promise._settlePromise
  [website]/[bluebird]/js/release/promise.js:566:21
- promise.js:606 Promise._settlePromiseCtx
  [website]/[bluebird]/js/release/promise.js:606:10
- async.js:138 Async._drainQueue
  [website]/[bluebird]/js/release/async.js:138:12
- async.js:143 Async._drainQueues
  [website]/[bluebird]/js/release/async.js:143:10
- async.js:17 Immediate.Async.drainQueues [as _onImmediate]
  [website]/[bluebird]/js/release/async.js:17:14
gatsby develop exited with code 1

Environment

Can’t seem to get gatsby info to work 🤔here’s the gatsby-named items from the yarn.lock

gatsby-cli@^2.0.0-beta.3, gatsby-cli@next:
  version "2.0.0-beta.3"
gatsby-link@^2.0.0-beta.4:
  version "2.0.0-beta.4"
gatsby-plugin-ngrok-tunneling@next:
  version "1.1.3"
gatsby-plugin-page-creator@^2.0.0-beta.2:
  version "2.0.0-beta.2"
gatsby-plugin-react-helmet@next:
  version "3.0.0-beta.3"
gatsby-plugin-resolve-src@next:
  version "1.1.3"
gatsby-plugin-sass@next:
  version "2.0.0-beta.3"
gatsby-plugin-sitemap@next:
  version "2.0.0-beta.2"
gatsby-react-router-scroll@^2.0.0-beta.2:
  version "2.0.0-beta.2"
gatsby-source-filesystem@next:
  version "2.0.1-beta.3"
gatsby@next:
  version "2.0.0-beta.17"

File contents (if changed)

gatsby-config.js:

module.exports = {
  siteMetadata: {
    siteUrl: 'https://www.website.com',
  },
  plugins: [
    'gatsby-plugin-react-helmet',
    'gatsby-plugin-sass',
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/src/pages`,
        name: 'pages',
      },
    },
    {
      resolve: `gatsby-plugin-sitemap`,
      options: {
        exclude: [
          '/thank-you',
          '/test',
          '/blog*',
          '/blog/*',
        ],
      },
    },
    'gatsby-plugin-resolve-src'
  ],
};

package.json:

{
  ...author info...
  "dependencies": {
    "@fortawesome/fontawesome": "^1.1.8",
    "@fortawesome/fontawesome-free-solid": "^5.0.13",
    "@fortawesome/fontawesome-svg-core": "^1.2.0",
    "@fortawesome/react-fontawesome": "^0.1.0",
    "async-request": "^1.2.0",
    "catalog": "^3.5.4",
    "chokidar-cli": "^1.2.0",
    "concurrently": "^3.6.0",
    "crypto": "^1.0.1",
    "g": "^2.0.1",
    "gatsby": "next",
    "gatsby-cli": "next",
    "gatsby-plugin-ngrok-tunneling": "next",
    "gatsby-plugin-react-helmet": "next",
    "gatsby-plugin-resolve-src": "next",
    "gatsby-plugin-sass": "next",
    "gatsby-plugin-sitemap": "next",
    "gatsby-source-filesystem": "next",
    "history": "^4.7.2",
    "html-entities": "^1.2.1",
    "ngrok": "^3.0.1",
    "node-sass-chokidar": "^1.1.0",
    "parameterize": "^0.1.0",
    "promise-polyfill": "8.0.0",
    "react": "^16.2.0",
    "react-anchor-link-smooth-scroll": "^1.0.10",
    "react-countup": "^3.0.3",
    "react-dom": "^16.2.0",
    "react-helmet": "^5.2.0",
    "react-redux": "^5.0.7",
    "react-router-hash-link": "^1.2.0",
    "react-tabs": "^2.2.2",
    "redux": "^4.0.0",
    "whatwg-fetch": "^2.0.4"
  },
  "keywords": [
    "gatsby"
  ],
  "license": "MIT",
  "main": "n/a",
  "scripts": {
    "build": "gatsby build",
    "style": "yarn catalog-start",
    "develop": "rm -rf .cache && concurrently --names \" WATCH, GATSBY\" -c \"bgBlue.bold\" --kill-others \"yarn watch-css\" \"gatsby develop\"",
    "developstyle": "rm -rf .cache && concurrently --names \" WATCH ,CATALOG, GATSBY\" -c \"bgBlue.bold\" --kill-others \"yarn watch-css\" \"yarn style\" \"gatsby develop\"",
    "format": "prettier --trailing-comma es5 --single-quote --write \"**/*.js\"",
    "lint": "eslint \"**/*.js\" && echo \"👍  Passed linting\n\"",
    "precommit": "yarn test && yarn lint && echo \"😎  Passed precommit steps. Commiting now.\n\"",
    "test": "echo \"👍  Passed tests (no tests defined yet)\n\"",
    "catalog-start": "catalog start",
    "catalog-build": "catalog build",
    "build-css": "node-sass-chokidar ./src/assets/stylesheets/application.scss -o ./catalog/css",
    "tunnel": "ngrok http 8000",
    "watch-css": "yarn build-css && chokidar ./src/assets/stylesheets/ -c \"yarn build-css\""
  },
  "devDependencies": {
    "css-loader": "^0.28.10",
    "eslint": "^5.0.1",
    "eslint-plugin-react": "^7.10.0",
    "husky": "^0.14.3",
    "node-sass": "^4.9.1",
    "prettier": "^1.13.7",
    "sass-loader": "^7.0.3",
    "style-loader": "^0.21.0"
  }
}

gatsby-node.js:

exports.onCreateWebpackConfig = require('./gatsby-node/webpack-config');
exports.sourceNodes = require('./gatsby-node/source-nodes');
exports.createPages = require('./gatsby-node/create-pages');
// ./gatsby-node/webpack-config
exports.onCreateWebpackConfig = require('./gatsby-node/webpack-config');
exports.sourceNodes = require('./gatsby-node/source-nodes');
exports.createPages = require('./gatsby-node/create-pages');
// ./gatsby-node/source-nodes/index.js
const getPages = require('./types/page');
const getPosts = require('./types/post');
const getEmployees = require('./types/employee');

// Create Nodes from API request
// Nodes are where data is kept in Graphql

module.exports = async ({ boundActionCreators }) => {
  const { createNode } = boundActionCreators;

  // Posts & pages requests run concurrently as not to
  // Bog down the event loop
  await Promise.all([
    getPosts(createNode),
    getPages(createNode),
    getEmployees(createNode),
  ]);

  return;
};
// ./gatsby-node/create-pages
const path = require('path');

// –––––– createPages ––––––

module.exports = ({ boundActionCreators, graphql }) => {
  const { createPage } = boundActionCreators;

  return new Promise(resolve => {
    // query JSON Pages

    const pageQuery = graphql(`
      {
        allJsonPage {
          edges {
            node {
              name
              slug
              id
              template
            }
          }
        }
      }
    `);

    pageQuery.then(result => {
      const nodes = result.data.allJsonPage.edges.map(edge => edge.node);

      nodes.forEach(node => {
        if (node.template === 'none' || !node.template) return;

        const pageConfig = {
          path: node.slug,
          component: path.resolve(`src/templates/${node.template}.js`),
          context: {
            name: node.name,
            slug: node.slug,
          },
        };

        createPage(pageConfig);
      });
    });

    // Query JSON posts

    const postQuery = graphql(`
      {
        allJsonPost {
          edges {
            node {
              name
              slug
              id
            }
          }
        }
      }
    `);

    postQuery.then(result => {
      const nodes = result.data.allJsonPost.edges.map(edge => edge.node);

      nodes.forEach(node => {
        const postConfig = {
          path: node.slug,
          component: path.resolve('src/templates/post.js'),
          context: {
            name: node.name,
            slug: node.slug,
          },
        };

        createPage(postConfig);
      });
    });

    // if all previous JS has run, Promise can be resolved

    resolve();
  }).catch(error => console.log(error));
};

gatsby-browser.js:

import React from 'react';
import { Router } from 'react-router-dom';
import { Provider } from 'react-redux';

import createStore from './src/state/createStore';

exports.replaceRouterComponent = ({ history }) => {
  const store = createStore();

  const ConnectedRouterWrapper = ({ children }) => (
    <Provider store={store}>
      <Router history={history}>{children}</Router>
    </Provider>
  );

  return ConnectedRouterWrapper;
};

gatsby-ssr.js:

import React from 'react';
import { Provider } from 'react-redux';
import { renderToString } from 'react-dom/server';

import createStore from './src/state/createStore';

exports.replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {
  const store = createStore();

  const ConnectedBody = () => (
    <Provider store={store}>{bodyComponent}</Provider>
  );

  replaceBodyHTMLString(renderToString(<ConnectedBody />));
};

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 18 (10 by maintainers)

Most upvoted comments

@gregoryforel the issue is that gatsby-node.js (CommonJS) is requiring (via ts-node) a Typescript file, which is an and of itself, fine.

However, the issue is that you’re presuming the “default” (i.e. module.exports) with this line in gatsby-node.js

exports.createPages = require('./createPages')

when createPages.ts actually contains

export const createPages = () => {};

so you can fix that in a few ways. Easiest is just changing the require statement in gatsby-node.js

exports.createPages = require('./createPages').createPages

@DSchau I should hire you 😉 Just solved this error too. I should not have tried to do everything at the same time: new to Gatsby, GraphQL, GraphCMS… If the user support keeps being like this, you guys have a great future