Compiling queries with Babel
If you prefer co-locating your GraphQL queries in your Javascript files, you typically use the
To avoid this runtime overhead, you can precompile your queries created with graphql-tag
using
- Using babel-plugin-graphql-tag
- Using graphql-tag.macro
- Using ts-transform-graphql-tagfor TypeScript
If you prefer to keep your GraphQL code in separate files (.graphql
or .gql
) you can use graphql-tag
under the hood, but transparently. You simply import
your operations/fragments as if each were an export from your GraphQL file. This carries the same precompilation benefits as the above approaches.
Using babel-plugin-graphql-tag
This approach will allow you to use the graphql-tag
library as usual, and when processing the files with this babel plugin, the calls to that library will be replaced by the precompiled result.
Install the plugin in your dev dependencies:
# with npmnpm install --save-dev babel-plugin-graphql-tag# or with yarnyarn add --dev babel-plugin-graphql-tag
Then add the plugin in your .babelrc
configuration file:
{"plugins": ["graphql-tag"]}
And that's it! All the usages of import gql from 'graphql-tag'
will be removed, and the calls to gql
will be replaced by the compiled version.
Using graphql-tag.macro
This approach is a bit more explicit, since you change all your usages of graphql-tag
for graphql-tag.macro
, which exports a gql
function that you can use the same way as the original one. This macro requires the graphql-tag
library untouched.
Why would you prefer this approach? Mainly because it requires less configuration (babel-macros
works with all kinds of macros, so if you already had it installed you don't have to do anything else), and also because of the explicitness. You can read more about the rationale of using babel-macros
To use it, provided that you
import gql from 'graphql-tag';const query = gql`query HelloWorld {hello {world}}`;
to this:
import gql from 'graphql-tag.macro'; // <-- Use the macroconst query = gql`query HelloWorld {hello {world}}`;
Using babel-plugin-import-graphql
Install the plugin in your dev dependencies:
# with npmnpm install --save-dev babel-plugin-import-graphql# or with yarnyarn add --dev babel-plugin-import-graphql
Then add the plugin in your .babelrc
configuration file:
{"plugins": ["import-graphql"]}
Now any import
statements importing from a GraphQL file type will return a ready-to-use GraphQL DocumentNode object.
import React, { Component } from 'react';import { graphql } from '@apollo/react-hoc';import myImportedQuery from './productsQuery.graphql';// or for files with multiple operations:// import { query1, query2 } from './queries.graphql';class QueryingComponent extends Component {render() {if (this.props.data.loading) return <h3>Loading...</h3>;return <div>{`This is my data: ${this.props.data.queryName}`}</div>;}}export default graphql(myImportedQuery)(QueryingComponent);
Using ts-transform-graphql-tag
Install the plugin in your dev dependencies:
# with npmnpm install --save-dev ts-transform-graphql-tag# or with yarnyarn add --dev ts-transform-graphql-tag
Read the
Fragments
All of these approaches support the use of fragments.
For the first two approaches, you can have fragments defined in a different call to gql
(either in the same file or in a different one). You can then include them into the main query using interpolation, like this:
import gql from 'graphql-tag';// or import gql from 'graphql-tag.macro';const fragments = {hello: gql`fragment HelloStuff on Hello {universegalaxy}`};const query = gql`query HelloWorld {hello {world...HelloStuff}}${fragments.hello}`;
With babel-plugin-import-graphql
, you can just include your fragment in your GraphQL file along-side whatever uses it, or even import it from a separate file using the #import
syntax. See the