Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apollo - React (Typescript) Invariant Error when building production build

I am creating a new react app with gatsby, typescript, and apollo (for graphql queries).

When testing in dev, the app compiles and runs with no errors thrown.

When I transpile the build, using 'gatsby build', it fails with an error.

I don't understand why or where this is being triggered. It seems to be something to do with the way webpack is checking as it's building, but I don't know how to pinpoint the issue and there doesn't seem to be any material out there with a clear answer for me.

It seems to be caused by the httplink module. The code that triggers the error when present in any .tsx file is:

import { HttpLink } from 'apollo-link-http'

const link = new HttpLink({
  uri: 'http://localhost:3001/graphql'
})

The error shown is the following:

error Building static HTML failed

See our docs page on debugging HTML builds for help https://gatsby.dev/debug-html

  10 |     function InvariantError(message) {
  11 |         if (message === void 0) { message = genericMessage; }
> 12 |         var _this = _super.call(this, typeof message ===     "number"
     | ^
  13 |             ? genericMessage + ": " + message + " (see    https://github.com/apollographql/invariant-packages)"
  14 |             : message) || this;
  15 |         _this.framesToPop = 1;


  WebpackError: Invariant Violation: Invariant Violation: 1 (see https://github.com/apollographql/invariant-packages)

  - invariant.esm.js:12 new InvariantError
[lib]/[apollo-link-http-common]/[ts-invariant]/lib/invariant.esm.js:12:1

  - bundle.esm.js:64 checkFetcher
[lib]/[apollo-link-http-common]/lib/bundle.esm.js:64:52

  - bundle.esm.js:8 createHttpLink
[lib]/[apollo-link-http]/lib/bundle.esm.js:8:17

  - bundle.esm.js:139 new HttpLink
[lib]/[apollo-link-http]/lib/bundle.esm.js:139:1

  - Strategy.tsx:6 Module../src/components/Strategy.tsx
lib/src/components/Strategy.tsx:6:14

  - bootstrap:19 __webpack_require__
lib/webpack/bootstrap:19:1


  - bootstrap:19 __webpack_require__
lib/webpack/bootstrap:19:1

  - sync-requires.js:10 Object../.cache/sync-requires.js
lib/.cache/sync-requires.js:10:56

  - bootstrap:19 __webpack_require__
lib/webpack/bootstrap:19:1

  - static-entry.js:9 Module../.cache/static-entry.js
lib/.cache/static-entry.js:9:22

  - bootstrap:19 __webpack_require__
lib/webpack/bootstrap:19:1

  - bootstrap:83
lib/webpack/bootstrap:83:1


  - universalModuleDefinition:3 webpackUniversalModuleDefinition
lib/webpack/universalModuleDefinition:3:1

  - universalModuleDefinition:10 Object.<anonymous>
lib/webpack/universalModuleDefinition:10:2"

Is this typescript issue, gatsby issue, apollo issue, or a webpack issue? Or a combination?

Thank you for any help you can give! I'm struggling with my understanding of all the pieces here.

I understand that Invariant Violations are about an issue with the wrong types being referenced. Because this occurs in the module, I'm not sure if I'm doing something wrong, or if it's an issue inside the imported library. Maybe it's an issue that I'm forcing typescript checks on a basic javascript based library. I still didn't quite come to a conclusion on this.

I tried adding the following config to gatsby-node.js to ignore the module checks (as suggested here: https://gatsby.dev/debug-html), with no successful build, though the error did change, as it could not see the module.

  exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
    if (stage === "build-html") {
      actions.setWebpackConfig({
        module: {
          rules: [
            {
              test: /apollo-link-http/,
              use: loaders.null(),
            },
          ],
        },
      })
    }
  }

To recap, this is the code designed to create the client object to enable queries to the graphql endpoint. When running 'gatsby build' the in variant error occurs (see above).

  import * as React from 'react'
  import { ApolloClient } from 'apollo-client'
  import { InMemoryCache } from 'apollo-cache-inmemory'
  import { HttpLink } from 'apollo-link-http'

  const cache = new InMemoryCache()
  const link = new HttpLink({
    uri: 'http://localhost:3001/graphql'
  })

  const client = new ApolloClient({
    cache,
    link
  })
like image 647
schredder Avatar asked May 27 '19 07:05

schredder


People also ask

Does Apollo have a typescript type system?

As your application grows, you may find it helpful to include a type system to assist in development. Apollo supports type definitions for TypeScript out of the box. Apollo Client ships with definitions in its associated npm package, so installation should be done for you after the libraries are included in your project.

How to use Apollo client inside a React component?

To be able to use this Apollo Client instance inside a React Component, we have to wrap the React component with a specific component called ApolloProvider. This accepts a single prop: client that is an instance of an ApolloClient. It’s time to pass our instance of ApolloClient to the ApolloProvider component.

How does Apollo server respond to GraphQL errors?

If a GraphQL error prevents Apollo Server from including any of the data you requested in its response, it responds with a 4xx status code. Apollo Server responds with a 200 status code if a GraphQL error occurred but the response still includes partial data. An operation that produces GraphQL errors might also return partial data.

What are syntax and resolver errors in Apollo server?

If a syntax error or validation error occurs, your server doesn't execute the operation at all because it's invalid. If resolver errors occur, your server can still return partial data. Learn more about GraphQL errors in the Apollo Server documentation.


1 Answers

I'm a newbie at this. After hours of looking I finally tracked down the error in the file. On closer inspection, when the environment is production (process.env.NODE_ENV === "production"), then the error is not detailed. So I looked at what the error would be if the environment was something else, and changed the file to output this to the console. What I got back was:

fetch is not found globally and no fetcher passed, to fix pass a fetch for
your environment like https://www.npmjs.com/package/node-fetch.

For example:
import fetch from 'node-fetch';
import { createHttpLink } from 'apollo-link-http';

const link = createHttpLink({ uri: '/graphql', fetch: fetch });

I added fetch to my code, and it built a production version with no errors.

I don't understand why this error was not thrown with the dev environment, but I guess it's something to do with the lazy loading.

Problem fixed.

like image 176
schredder Avatar answered Oct 24 '22 02:10

schredder