Yusinto Ngadiman
December 12, 2016·2 min read

Building graphql schema without babelrc

Man it has been a busy month! It's been a while since I blogged, I have to say I miss it a lot. Almost as much as I miss drinking..

Today I'll be talking about graphql and relay, specifically about building the schema. Warning this is not a beginner's guide to graphql and relay, there are tons of other tutorials which can help you with that. This blog is about decoupling your graphql schema build from your project's .babelrc file.

The problem

Your project has a .babelrc file which contains presets, plugins, etc used by babel when you run your app. You need to include babelRelayPlugin in your .babelrc plugins section so your relay app can comprehend your graphql schema.

However, babelRelayPlugin.js contains a reference to schema.json which is generated by babel-node updateSchema.js which in turn uses .babelrc which has a dependency on babelRelayPlugin which is a cyclic dependency which gives me a migraine.

The solution

We need to decouple graphql schema generation from app runtime. The standard .babelrc file is required for our app runtime so that stays. That means we cannot depend on .babelrc for our schema generation i.e. when running updateSchema.js we can't use babel-node. Instead we use plain vanilla node in combination with babel-register with inline config when running updateSchema.

Enough talk, show me some code

You need the following babel packages:

sudo yarn add --dev babel-polyfill babel-preset-latest
sudo yarn add babel-register babel-preset-stage-0

In your package.json, you declare an npm run command update-schema which points an index.js file:

"scripts": {
    "update-schema": "node ./src/graphql/index.js",
    ...
}

Your src/graphql/index.js then looks like this:

require('babel-register')({
  babelrc: false,
  presets: [
    "latest"
  ]
});
require("babel-polyfill"); // required for async generators
require('./updateSchema');

where updateSchema.js is provided by facebook here.

Conclusion

Check out the sample code for a working example and let me know if this is useful (or not)!