graphqlreact-apollonpm-runpostgraphql

run postgraphile with npm


I'm working on a react app and using apollo and postgraphile for graphql. I currently have to have two terminal windows open, one running

npm start 

for the react-dev server, and one running

postgraphile -c 'postgresstring'

for the postgraphile server

everything works when doing this, but i'm passing the project off to the rest of my team and would like them to be able to simply run

npm start

to start both the react and postgraphile servers. I tried using the npm packages concurrently and npm-start-all to run both scripts on npm start, but every time i use npm to run the postgraphile command I get errors on trying to actually query the graphql server in graphiql saying that i have duplicate instances of graphql running. this happens even if i put the postgraphile command in it's own npm command like

"graphql": "postgraphile -c 'postgresstring'"

and run

npm run graphql

error message:

Error: Cannot use GraphQLSchema "[object Object]" from another module or realm.

Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of 
other relied on modules, use "resolutions" to ensure only one version 
is installed.

https://yarnpkg.com/en/docs/selective-version-resolutions

Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.

How can I run postgraphile via npm run so that i can use concurrently or npm-run-all to run both of them with a single command? note that simply using "node scripts/start.js && postgraphile -c 'postgresstring'" won't work because it waits for the start.js server to terminate before running postgraphile.


Solution

  • This is a common pain for people working with graphql in the Node.js ecosystem. The way to solve this is to add a "resolutions" entry to your package.json informing yarn that it should try and install just one version, graphql@0.12.x, anywhere that version satisfies the supported GraphQL ranges rather than installing multiple versions. To do so, add something like this to your package.json file:

    "resolutions": {
      "graphql": "0.12.x"
    }
    

    Then run yarn again and you should notice that your yarn.lock file has been updated to only reference one version of graphql.


    Explanation

    The first postgraphile command you're running executes the globally installed postgraphile command (installed via npm install -g postgraphile or yarn global add postgraphile); which doesn't suffer this issue because it has only its own dependencies and they don't conflict.

    However for the npm run command, npm automatically adds your local ./node_modules/.bin/ folder to the beginning of $PATH and thus your local copy of postgraphile (installed via yarn add postgraphile) is being executed instead. (This is the behaviour you want!) It seems you've also installed something else that depends on graphql (perhaps Apollo Client?) and you now have two versions of graphql somewhere in your node_modules folder, each in different locations, and postgraphile is picking up a different version to graphile-build, which is causing the issue.

    Happy PostGraphiling!