gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.27k stars 10.31k forks source link

[v2] gatsbyNode[api] is not a function #6313

Closed colbyfayock closed 6 years ago

colbyfayock commented 6 years ago

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 />));
};
m-allanson commented 6 years ago

I'm not sure what's causing that... as a debugging step I'd try moving the code from your various ./gatsby-node/ requires back into the main gatsby-node.js. If that works, then move things out bit by bit until you can reproduce the error.

colbyfayock commented 6 years ago

good call. it looks like the webpack config import was the offender, perhaps there's an issue with the export. will just carry on with that particular one in the gatsby-node file. thanks for the help

gregoryforel commented 6 years ago

@colbyfayock Have you ever found out? Facing the same error message. Thanks!

DSchau commented 6 years ago

@gregoryforel could you share a repo or reproduction of the issue? It's likely that you're exporting an API (i.e. in a file) that isn't an actual Gatsby API!

colbyfayock commented 6 years ago

@gregoryforel it had to do with how I was running the exports relating to the custom webpack config, but i didn't ever figure out the exact issue as we didn't even need the custom config anymore. if you're able to provide some code to look at like DSchau mentioned, we might be able to help debug

gregoryforel commented 6 years ago

@DSchau Thanks! Here you go: https://github.com/gregoryforel/gatsby-typescript-graphcms

gregoryforel commented 6 years ago

@colbyfayock @DSchau I'm really new to Gatsby and GraphCMS. So far, just trying to setup a starterkit to be able to work in Typescript. I'm almost there, it was working before I tried to what clarkdave described in this thread, very last post: https://github.com/gatsbyjs/gatsby/issues/1457

DSchau commented 6 years ago

@gregoryforel so we're in agreement that the repo (as authored) works just fine, right? I wasn't able to reproduce any errors!

It seems like you run into errors when you start requiring ts-node?

gregoryforel commented 6 years ago

@DSchau Indeed. That's what I get:

yarn run v1.7.0
$ gatsby develop
success open and validate gatsby-config β€” 0.006 s
success load plugins β€” 0.173 s
success onPreInit β€” 0.323 s
success delete html and css files from previous builds β€” 0.012 s
success initialize cache β€” 0.021 s
success copy gatsby files β€” 0.076 s
success onPreBootstrap β€” 0.012 s
success source and transform nodes β€” 0.429 s
success building schema β€” 0.115 s
error gatsby-node.js returned an error

  TypeError: gatsbyNode[api] is not a function

  - api-runner-node.js:136 runAPI
    [gatsby-source-graphql]/[gatsby]/src/utils/api-runner-node.js:136:22

  - api-runner-node.js:242 runAPI
    [gatsby-source-graphql]/[gatsby]/src/utils/api-runner-node.js:242:9

  - util.js:16 tryCatcher
    [gatsby-source-graphql]/[bluebird]/js/release/util.js:16:23

  - reduce.js:155 Object.gotValue
    [gatsby-source-graphql]/[bluebird]/js/release/reduce.js:155:18

  - reduce.js:144 Object.gotAccum
    [gatsby-source-graphql]/[bluebird]/js/release/reduce.js:144:25

  - util.js:16 Object.tryCatcher
    [gatsby-source-graphql]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:614:10

  - promise.js:694 Promise._settlePromises
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:694:18

  - async.js:138 _drainQueueStep
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:138:12

  - async.js:131 _drainQueue
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:131:9

  - async.js:147 Async._drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:147:5

  - async.js:17 Immediate.Async.drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:17:14

error Cannot read property 'filter' of undefined

  TypeError: Cannot read property 'filter' of undefined

  - api-runner-node.js:266 filter
    [gatsby-source-graphql]/[gatsby]/src/utils/api-runner-node.js:266:42

  - util.js:16 tryCatcher
    [gatsby-source-graphql]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:614:10

  - promise.js:694 Promise._settlePromises
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:694:18

  - async.js:138 _drainQueueStep
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:138:12

  - async.js:131 _drainQueue
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:131:9

  - async.js:147 Async._drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:147:5

  - async.js:17 Immediate.Async.drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:17:14

error UNHANDLED REJECTION

  TypeError: Cannot read property 'filter' of undefined

  - api-runner-node.js:266 filter
    [gatsby-source-graphql]/[gatsby]/src/utils/api-runner-node.js:266:42

  - util.js:16 tryCatcher
    [gatsby-source-graphql]/[bluebird]/js/release/util.js:16:23

  - promise.js:512 Promise._settlePromiseFromHandler
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:512:31

  - promise.js:569 Promise._settlePromise
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:569:18

  - promise.js:614 Promise._settlePromise0
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:614:10

  - promise.js:694 Promise._settlePromises
    [gatsby-source-graphql]/[bluebird]/js/release/promise.js:694:18

  - async.js:138 _drainQueueStep
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:138:12

  - async.js:131 _drainQueue
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:131:9

  - async.js:147 Async._drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:147:5

  - async.js:17 Immediate.Async.drainQueues
    [gatsby-source-graphql]/[bluebird]/js/release/async.js:17:14

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
DSchau commented 6 years ago

@gregoryforel would you mind "breaking it" in a branch or something of the repo?

gregoryforel commented 6 years ago

What do you mean exactly?

DSchau commented 6 years ago

@gregoryforel it's hard for me to reproduce exactly what you have (that's broken) if I can't see how it's broken! The repo in its current state works just fine!

gregoryforel commented 6 years ago

@DSchau I'm so stupid... I forgot to commit my changes, I pushed the working repo. Sorry for that. Check the bugfix branch please, just uploaded it.

DSchau commented 6 years ago

@gregoryforel definitely not! Happens to all of us! Checking it out now.

DSchau commented 6 years ago

@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
gregoryforel commented 6 years ago

@DSchau Thank you so much, I would not have caught that. I'm peeling the onion, now seeing other errors, but I should manage. Cheers

DSchau commented 6 years ago

@gregoryforel yup yup, I saw a few too :) One of them is the result of the graphql function call is an object containing a data property which contains the result of the GraphQL query. So you just need one more data subproperty, and it should be mostly good after that!

And you're very welcome. Thanks for using Gatsby πŸ’œ

gregoryforel commented 6 years ago

@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