Helpful utilities for parsing GraphQL queries. Includes:
gql
A JavaScript template literal tag that parses GraphQL query strings into the standard GraphQL AST./loader
A webpack loader to preprocess queries
graphql-tag
uses the reference graphql
library under the hood as a peer dependency, so in addition to installing this module, you'll also have to install graphql-js
.
This is a template literal tag you can use to concisely write a GraphQL query that is parsed into the standard GraphQL AST:
import gql from 'graphql-tag';
const query = gql`
{
user(id: 5) {
firstName
lastName
}
}
`
// query is now a GraphQL syntax tree object
console.log(query);
// {
// "kind": "Document",
// "definitions": [
// {
// "kind": "OperationDefinition",
// "operation": "query",
// "name": null,
// "variableDefinitions": null,
// "directives": [],
// "selectionSet": {
// "kind": "SelectionSet",
// "selections": [
// {
// "kind": "Field",
// "alias": null,
// "name": {
// "kind": "Name",
// "value": "user",
// ...
You can easily explore GraphQL ASTs on astexplorer.net.
This package is the way to pass queries into Apollo Client. If you're building a GraphQL client, you can use it too!
GraphQL strings are the right way to write queries in your code, because they can be statically analyzed using tools like eslint-plugin-graphql. However, strings are inconvenient to manipulate, if you are trying to do things like add extra fields, merge multiple queries together, or other interesting stuff.
That's where this package comes in - it lets you write your queries with ES2015 template literals and compile them into an AST with the gql
tag.
This package only has one feature - it caches previous parse results in a simple dictionary. This means that if you call the tag on the same query multiple times, it doesn't waste time parsing it again. It also means you can use ===
to compare queries to check if they are identical.
GraphQL queries can be compiled at build time using babel-plugin-graphql-tag. Pre-compiling queries decreases the script initialization time and reduces the bundle size by potentially removing the need for graphql-tag
at runtime.
Try this custom transformer to pre-compile your GraphQL queries in TypeScript: ts-transform-graphql-tag.
Additionally, in certain situations, preprocessing queries via the webpack loader is not possible. babel-plugin-import-graphql will allow one to import graphql files directly into your JavaScript by preprocessing GraphQL queries into ASTs at compile-time.
E.g.:
import myImportedQuery from './productsQuery.graphql'
class ProductsPage extends React.Component {
...
}
create-react-app@2.0.0
does support the ability to preprocess queries using evenchange4/graphql.macro.
If you're using an older version of create-react-app
, check out react-app-rewire-inline-import-graphql-ast to preprocess queries without needing to eject.
This package also includes a webpack loader. There are many benefits over this approach, which saves GraphQL ASTs processing time on client-side and enable queries to be separated from script over .graphql
files.
loaders: [
{
test: /\.(graphql|gql)$/,
exclude: /node_modules/,
loader: 'graphql-tag/loader'
}
]
then:
import query from './query.graphql';
console.log(query);
// {
// "kind": "Document",
// ...
Testing environments that don't support Webpack require additional configuration. For Jest use jest-transform-graphql.
With the webpack loader, you can also import operations by name:
In a file called query.gql
:
query MyQuery1 {
...
}
query MyQuery2 {
...
}
And in your JavaScript:
import { MyQuery1, MyQuery2 } from 'query.gql'
This package will emit a warning if you have multiple fragments of the same name. You can disable this with:
import { disableFragmentWarnings } from 'graphql-tag';
disableFragmentWarnings()
This package exports an experimentalFragmentVariables
flag that allows you to use experimental support for parameterized fragments.
You can enable / disable this with:
import { enableExperimentalFragmentVariables, disableExperimentalFragmentVariables } from 'graphql-tag';
Enabling this feature allows you declare documents of the form
fragment SomeFragment ($arg: String!) on SomeType {
someField
}