gatsbyjs / gatsby

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

Building fails because fetch is not defined #3006

Closed thibmaek closed 6 years ago

thibmaek commented 6 years ago
gatsby-config.js ```js require(`dotenv`).config(); module.exports = { siteMetadata: { author: `Thibault Maekelbergh`, keywords: `thibault maekelbergh, thibmaek, blog`, title: `A nice blog about development, Raspberry Pi, plants and probably records`, social: { github: `thibmaek`, twitter: `thibmaek`, }, }, plugins: [ `gatsby-plugin-react-helmet`, `gatsby-transformer-remark`, { resolve: `gatsby-source-contentful`, options: { accessToken: process.env.CONTENTFUL_TOKEN, spaceId: process.env.CONTENTFUL_SPACEID, }, }, ], }; ```
gatsby-node.js ```js const path = require(`path`); const postTemplate = path.resolve(`./src/templates/post.jsx`); exports.createPages = ({ graphql, boundActionCreators }) => { const { createPage } = boundActionCreators; return new Promise(async (resolve, reject) => { try { const posts = await graphql(` { allContentfulPost(limit: 1000) { edges { node { id slug } } } } `); if (posts.errors) reject(posts.errors); posts.data.allContentfulPost.edges.forEach(edge => { createPage({ component: postTemplate, context: { id: edge.node.id, slug: edge.node.slug, }, path: `/post/${edge.node.slug}/`, }); }); resolve(); } catch (e) { console.error(e); reject(e); } }); }; ```

Trying to run gatsby build fails because it can not find fetch:

error Building static HTML for pages failed

See our docs page on debugging HTML builds for help https://goo.gl/yL9lND

  12 | 
  13 |   componentWillMount() {
> 14 |     fetch(process.env.GATSBY_RECENT_REPOS_URL)
     |     ^
  15 |       .then(r => r.json())
  16 |       .then(repos => {
  17 |         this.setState({ repos: repos.reverse() });

  WebpackError: fetch is not defined

  - index.jsx:14 RecentRepos.componentWillMount
    src/components/recent-repos/index.jsx:14:5

  - ReactCompositeComponent.js:348 ReactCompositeComponentWrapper.performInitialMount
    ~/react-dom/lib/ReactCompositeComponent.js:348:1

  - ReactCompositeComponent.js:255 ReactCompositeComponentWrapper.mountComponent
    ~/react-dom/lib/ReactCompositeComponent.js:255:1

  - ReactReconciler.js:43 Object.mountComponent
    ~/react-dom/lib/ReactReconciler.js:43:1

I tried polyfilling this with unfetch, node-fetch, isomorphic-fetch, whatwg-fetch and none of these worked. I think it might be an issue, if not where do I start to fix this?

KyleAMathews commented 6 years ago

Try importing fetch instead of doing a polyfill.

thibmaek commented 6 years ago

@KyleAMathews Tried both import 'isomorphic-fetch' and import fetch from 'ismorphic-fetch'

Did this with node-fetch, whatwg-fetch, isomorphic-fetch and unfetch. None of them seemed to work

calpa commented 6 years ago

@thibmaek you may use axios instead of fetch.

thibmaek commented 6 years ago

@calpa I might, but that's really not a solution though but an alternative. Seems weird that I could use all the nice ES6 & ESNext stuff out of the box with Gatsby, but I shouldn't use a widely supported API in the official Javascript spec.

thibmaek commented 6 years ago

@calpa I tried it out with axios but the same deal:

error Building static HTML for pages failed

See our docs page on debugging HTML builds for help https://goo.gl/yL9lND

  27 |   message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.';
  28 | 
> 29 |   var error = new Error(message);
     | ^
  30 |   error.name = 'Invariant Violation';
  31 |   error.framesToPop = 1; // we don't care about reactProdInvariant's own frame
  32 | 

  WebpackError: Minified React error #130; visit http://facebook.github.io/react/docs/error-decoder.html?invariant=130&args[]=object&a  rgs[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

which results in this:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.[missing argument]

Works fine in dev for this endpoint: https://gh-latest-repos-ohdfptbedm.now.sh/

thibmaek commented 6 years ago

Seems like I was able to build using isomorphic-fetch to polyfill fetch not being defined. The last error was related to placeholder files in pages/ which were empty or did not export a valid React component.

ciffelia commented 6 years ago

If you don't need polyfill for IE, you may use this code without isomorphic-fetch

typeof window !== 'undefined' && window.fetch(...)
  .then(...)
  .catch(...)
KyleAMathews commented 6 years ago

@kodepareek this wasn't ever an issue with Gatsby code. If you're seeing this issue with builds, try one of the above solutions on your code.

kilgarenone commented 6 years ago

Does anyone know how to integrate the whatwg-fetch library in gatsby?

What I have done so far is import 'whatwg-fetch'; in the gatsby-browser.js. Now I'm not sure how to add it as a first element in the webpack's entry property presumably in the gatsby-node.js.

KyleAMathews commented 6 years ago

@kilgarenone you need to import it into the modules that you're using fetch e.g. import fetch from 'whatwg-fetch'

kilgarenone commented 6 years ago

Oh that's it? I don't have to do any of the steps suggested here https://github.com/github/fetch#installation other than the npm install?

EDIT: Doesn't seem to work. It gives me e.response is undefined error

fivetwelve commented 5 years ago

Hopefully, the following helps someone out; it took me a while.

I was struggling today with implementing a simple request with whatwg-fetch. After seeing some errors between develop & build I used import { fetch as fetchPolyfill } from 'whatwg-fetch';.

When using v3.0.0, fetchPolyfill under develop works correctly, but during build stops on:

TypeError: Cannot read property 'path' of undefined

  - build.js:68 buildHTML.catch.err
    [my-site]/[gatsby]/dist/commands/build.js:68:72

    [... error chain continues]

When I try to downgrade to v2.0.4, (c.f. PR https://github.com/pinvite/pinvite/pull/23 referenced in https://github.com/gatsbyjs/gatsby/issues/8612) build succeeds but in develop the browser throws:

TypeError: Object(...) is not a function

 componentDidMount() {
> 61 |   fetchPolyfill('/.netlify/functions/getCustomer')
  62 |     .then(res => res.json())
  63 |     .then(json => {
  64 |       this.setState({

Unfortunately I couldn't use isomorphic-fetch either on account of its dependancy on whatwg-fetch. https://github.com/matthew-andrews/isomorphic-fetch/issues/174

However, fetch-ponyfill didn't throw any errors in either build nor develop so that ended up being my solution for now. I'd love to know if anyone has figured out a different and stable approach that might be more widely-accepted.

(I'm using gatsby v2.0.106)

stewest commented 3 years ago

You could do something like this using React Context ("outside" of Gatsby - client side)

Isomorphic Fetch - with React hook