Skip to content

Commit

Permalink
Merge branch 'master' of github.com:apollographql/graphql-tag
Browse files Browse the repository at this point in the history
  • Loading branch information
jnwng committed Feb 7, 2018
2 parents ecd2dc0 + 8b34c3a commit 7fd462d
Show file tree
Hide file tree
Showing 7 changed files with 397 additions and 43 deletions.
79 changes: 56 additions & 23 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,46 +25,79 @@
[PR #99](https://github.com/apollographql/graphql-tag/pull/99)

### v2.3.0
<<<<<<< HEAD
- Add flow support [michalkvasnicak](https://github.com/michalkvasnicak) in [PR #98](https://github.com/apollographql/graphql-tag/pull/98)
=======

* Add flow support [michalkvasnicak](https://github.com/michalkvasnicak) in
[PR #98](https://github.com/apollographql/graphql-tag/pull/98)
>>>>>>> 8b34c3ac6bc67165c114b0f0e6ddf4549312a2c4
### v2.2.2
- Make parsing line endings kind agnostic [vlasenko](https://github.com/vlasenko) in [PR #95](https://github.com/apollographql/graphql-tag/pull/95)

* Make parsing line endings kind agnostic [vlasenko](https://github.com/vlasenko) in
[PR #95](https://github.com/apollographql/graphql-tag/pull/95)

### v2.2.1
- Fix #61: split('/n') does not work on Windows [dnalborczyk](https://github.com/dnalborczyk) in [PR #89](https://github.com/apollographql/graphql-tag/pull/89)

* Fix #61: split('/n') does not work on Windows [dnalborczyk](https://github.com/dnalborczyk) in
[PR #89](https://github.com/apollographql/graphql-tag/pull/89)

### v2.2.0
- Bumping `graphql` peer dependency to ^0.10.0 [dotansimha](https://github.com/dotansimha) in [PR #85](https://github.com/apollographql/graphql-tag/pull/85)

* Bumping `graphql` peer dependency to ^0.10.0 [dotansimha](https://github.com/dotansimha) in
[PR #85](https://github.com/apollographql/graphql-tag/pull/85)

### v2.1.0
- Add support for calling `gql` as a function [matthewerwin](https://github.com/matthewerwin) in [PR #66](https://github.com/apollographql/graphql-tag/pull/66)
- Including yarn.lock file [PowerKiKi](https://github.com/PowerKiKi) in [PR #72](https://github.com/apollographql/graphql-tag/pull/72)
- Ignore duplicate fragments when using the Webpack loader [czert](https://github.com/czert) in [PR #52](https://github.com/apollographql/graphql-tag/pull/52)
- Fixing `graphql-tag/loader` by properly stringifying GraphQL Source [jnwng](https://github.com/jnwng) in [PR #65](https://github.com/apollographql/graphql-tag/pull/65)

* Add support for calling `gql` as a function [matthewerwin](https://github.com/matthewerwin) in
[PR #66](https://github.com/apollographql/graphql-tag/pull/66)
* Including yarn.lock file [PowerKiKi](https://github.com/PowerKiKi) in
[PR #72](https://github.com/apollographql/graphql-tag/pull/72)
* Ignore duplicate fragments when using the Webpack loader [czert](https://github.com/czert) in
[PR #52](https://github.com/apollographql/graphql-tag/pull/52)
* Fixing `graphql-tag/loader` by properly stringifying GraphQL Source [jnwng](https://github.com/jnwng) in
[PR #65](https://github.com/apollographql/graphql-tag/pull/65)

### v2.0.0
Restore dependence on `graphql` module [abhiaiyer91](https://github.com/abhiaiyer91) in [PR #46](https://github.com/apollographql/graphql-tag/pull/46) addressing [#6](https://github.com/apollographql/graphql-tag/issues/6)
- Added `graphql` as a [peerDependency](https://github.com/apollographql/graphql-tag/commit/ac061dd16440e75c166c85b4bff5ba06c79c9356)

Restore dependence on `graphql` module [abhiaiyer91](https://github.com/abhiaiyer91) in
[PR #46](https://github.com/apollographql/graphql-tag/pull/46) addressing
[#6](https://github.com/apollographql/graphql-tag/issues/6)

* Added `graphql` as a
[peerDependency](https://github.com/apollographql/graphql-tag/commit/ac061dd16440e75c166c85b4bff5ba06c79c9356)

### v1.3.2
- Add typescript definitions for the bundledPrinter [PR #63](https://github.com/apollographql/graphql-tag/pull/63)

* Add typescript definitions for the bundledPrinter [PR #63](https://github.com/apollographql/graphql-tag/pull/63)

### v1.3.1
- Making sure not to log deprecation warnings for internal use of deprecated module [jnwng](https://github.com/jnwng) addressing [#54](https://github.com/apollographql/graphql-tag/issues/54#issuecomment-283301475)

* Making sure not to log deprecation warnings for internal use of deprecated module [jnwng](https://github.com/jnwng)
addressing [#54](https://github.com/apollographql/graphql-tag/issues/54#issuecomment-283301475)

### v1.3.0
- Bump bundled `graphql` packages to v0.9.1 [jnwng](https://github.com/jnwng) in [PR #55](https://github.com/apollographql/graphql-tag/pull/55).
- Deprecate the `graphql/language/parser` and `graphql/language/printer` exports [jnwng](https://github.com/jnwng) in [PR #55](https://github.com/apollographql/graphql-tag/pull/55)

* Bump bundled `graphql` packages to v0.9.1 [jnwng](https://github.com/jnwng) in
[PR #55](https://github.com/apollographql/graphql-tag/pull/55).
* Deprecate the `graphql/language/parser` and `graphql/language/printer` exports [jnwng](https://github.com/jnwng) in
[PR #55](https://github.com/apollographql/graphql-tag/pull/55)

### v1.2.4
Restore Node < 6 compatibility. [DragosRotaru](https://github.com/DragosRotaru) in [PR #41](https://github.com/apollographql/graphql-tag/pull/41) addressing [#39](https://github.com/apollographql/graphql-tag/issues/39)

Restore Node < 6 compatibility. [DragosRotaru](https://github.com/DragosRotaru) in
[PR #41](https://github.com/apollographql/graphql-tag/pull/41) addressing
[#39](https://github.com/apollographql/graphql-tag/issues/39)

### v1.2.1

Fixed an issue with fragment imports. [PR #35](https://github.com/apollostack/graphql-tag/issues/35).

### v1.2.0

Added ability to import other GraphQL documents with fragments using `#import` comments. [PR #33](https://github.com/apollostack/graphql-tag/pull/33)
Added ability to import other GraphQL documents with fragments using `#import` comments.
[PR #33](https://github.com/apollostack/graphql-tag/pull/33)

### v1.1.2

Expand All @@ -83,7 +116,7 @@ You can disable this with:
```js
import { disableFragmentWarnings } from 'graphql-tag';

disableFragmentWarnings()
disableFragmentWarnings();
```

### v1.0.0
Expand All @@ -92,34 +125,34 @@ Releasing 0.1.17 as 1.0.0 in order to be explicit about Semantic Versioning.

### v0.1.17

- Allow embedding fragments inside document strings, as in
* Allow embedding fragments inside document strings, as in

```js
import gql from 'graphql-tag';

const fragment = gql`
fragment Foo on Bar {
field
}
fragment Foo on Bar {
field
}
`;

const query = gql`
{
...Foo
}
${Foo}
`
`;
```

See also http://dev.apollodata.com/react/fragments.html

### v0.1.16

- Add caching to Webpack loader. [PR #16](https://github.com/apollostack/graphql-tag/pull/16)
* Add caching to Webpack loader. [PR #16](https://github.com/apollostack/graphql-tag/pull/16)

### v0.1.15

- Add Webpack loader to `graphql-tag/loader`.
* Add Webpack loader to `graphql-tag/loader`.

### v0.1.14

Expand Down
64 changes: 61 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
[![Build Status](https://travis-ci.org/apollographql/graphql-tag.svg?branch=master)](https://travis-ci.org/apollographql/graphql-tag)
[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://www.apollodata.com/#slack)

GraphQL printing and parsing with bundled dependencies. Includes:
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](https://github.com/graphql/graphql-js) under the hood as a peer dependency, so in addition to installing this module, you'll also have to install `graphql-js`.

### gql

This is a template literal tag you can use to concisely write a GraphQL query that is parsed into the standard GraphQL AST:
Expand Down Expand Up @@ -62,9 +64,35 @@ That's where this package comes in - it lets you write your queries with [ES2015

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.

### Webpack preprocessing
### Babel preprocessing

GraphQL queries can be compiled at build time using [babel-plugin-graphql-tag](https://github.com/gajus/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.

#### TypeScript
Try this custom transformer to pre-compile your GraphQL queries in TypeScript: [ts-transform-graphql-tag](https://github.com/firede/ts-transform-graphql-tag).

#### React Native, Next.js

This package also includes a [webpack loader](https://webpack.github.io/docs/loaders.html). 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.
Additionally, in certain situations, preprocessing queries via the webpack loader is not possible. [babel-plugin-inline-import-graphql-ast](https://www.npmjs.com/package/babel-plugin-inline-import-graphql-ast) will allow one to import graphql files directly into your JavaScript by preprocessing GraphQL queries into ASTs at compile-time.

E.g.:
```javascript
import myImportedQuery from './productsQuery.graphql'

class ProductsPage extends React.Component {
...
}
```

#### Create-React-App

`[email protected]` will [support the ability to preprocess queries](https://github.com/facebook/create-react-app/pull/3909) using `graphql-tag/loader` without the need to eject.

If you're using an older version of `create-react-app`, check out [react-app-rewire-inline-import-graphql-ast](https://www.npmjs.com/package/react-app-rewire-inline-import-graphql-ast) to preprocess queries without needing to eject.

### Webpack preprocessing with `graphql-tag/loader`

This package also includes a [webpack loader](https://webpack.js.org/concepts/loaders). 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.

```js
loaders: [
Expand All @@ -88,3 +116,33 @@ console.log(query);
```

Testing environments that don't support Webpack require additional configuration. For [Jest](https://facebook.github.io/jest/) use [jest-transform-graphql](https://github.com/remind101/jest-transform-graphql).

#### Support for multiple operations

With the webpack loader, you can also import operations by name:

In a file called `query.gql`:
```graphql
query MyQuery1 {
...
}

query MyQuery2 {
...
}
```

And in your JavaScript:
```javascript
import { MyQuery1, MyQuery2 } from 'query.gql'
```

### Warnings

This package will emit a warning if you have multiple fragments of the same name. You can disable this with:

```js
import { disableFragmentWarnings } from 'graphql-tag';

disableFragmentWarnings()
```
4 changes: 3 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export default function gql(literals: any, ...placeholders: any[]): any;
import { DocumentNode } from 'graphql';

export default function gql(template: TemplateStringsArray, ...substitutions: any[]): DocumentNode;
export function resetCaches(): void;
export function disableFragmentWarnings(): void;
126 changes: 124 additions & 2 deletions loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,133 @@ function expandImports(source, doc) {
module.exports = function(source) {
this.cacheable();
const doc = gql`${source}`;
const outputCode = `
let headerCode = `
var doc = ${JSON.stringify(doc)};
doc.loc.source = ${JSON.stringify(doc.loc.source)};
`;

let outputCode = "";

// Allow multiple query/mutation definitions in a file. This parses out dependencies
// at compile time, and then uses those at load time to create minimal query documents
// We cannot do the latter at compile time due to how the #import code works.
let operationCount = doc.definitions.reduce(function(accum, op) {
if (op.kind === "OperationDefinition") {
return accum + 1;
}

return accum;
}, 0);

if (operationCount <= 1) {
outputCode += `
module.exports = doc;
`
} else {
outputCode +=`
// Collect any fragment/type references from a node, adding them to the refs Set
function collectFragmentReferences(node, refs) {
if (node.kind === "FragmentSpread") {
refs.add(node.name.value);
} else if (node.kind === "VariableDefinition") {
var type = node.type;
if (type.kind === "NamedType") {
refs.add(type.name.value);
}
}
if (node.selectionSet) {
node.selectionSet.selections.forEach(function(selection) {
collectFragmentReferences(selection, refs);
});
}
if (node.variableDefinitions) {
node.variableDefinitions.forEach(function(def) {
collectFragmentReferences(def, refs);
});
}
if (node.definitions) {
node.definitions.forEach(function(def) {
collectFragmentReferences(def, refs);
});
}
}
var definitionRefs = {};
(function extractReferences() {
doc.definitions.forEach(function(def) {
if (def.name) {
var refs = new Set();
collectFragmentReferences(def, refs);
definitionRefs[def.name.value] = refs;
}
});
})();
function findOperation(doc, name) {
return doc.definitions.find(function(op) {
return op.name ? op.name.value == name : false;
});
}
function oneQuery(doc, operationName) {
// Copy the DocumentNode, but clear out the definitions
var newDoc = Object.assign({}, doc);
var op = findOperation(doc, operationName);
newDoc.definitions = [op];
// Now, for the operation we're running, find any fragments referenced by
// it or the fragments it references
var opRefs = definitionRefs[operationName] || new Set();
var allRefs = new Set();
var newRefs = new Set(opRefs);
while (newRefs.size > 0) {
var prevRefs = newRefs;
newRefs = new Set();
prevRefs.forEach(function(refName) {
if (!allRefs.has(refName)) {
allRefs.add(refName);
var childRefs = definitionRefs[refName] || new Set();
childRefs.forEach(function(childRef) {
newRefs.add(childRef);
});
}
});
}
allRefs.forEach(function(refName) {
var op = findOperation(doc, refName);
if (op) {
newDoc.definitions.push(op);
}
});
return newDoc;
}
module.exports = doc;
`

for (const op of doc.definitions) {
if (op.kind === "OperationDefinition") {
if (!op.name) {
throw "Query/mutation names are required for a document with multiple definitions";
}

const opName = op.name.value;
outputCode += `
module.exports["${opName}"] = oneQuery(doc, "${opName}");
`
}
}
}

const importOutputCode = expandImports(source, doc);
const allCode = headerCode + os.EOL + importOutputCode + os.EOL + outputCode + os.EOL;

return outputCode + os.EOL + importOutputCode + os.EOL + `module.exports = doc;`;
return allCode;
};
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@
"url": "https://github.com/apollostack/graphql-tag/issues"
},
"homepage": "https://github.com/apollostack/graphql-tag#readme",
"dependencies": {},
"dependencies": {
"@types/graphql": ">=0.8.6 <=0.11.7"
},
"devDependencies": {
"babel-preset-es2015": "^6.9.0",
"babel-register": "^6.9.0",
"chai": "^4.0.2",
"graphql": "^0.10.0",
"graphql": "^0.11.0",
"mocha": "^3.4.1",
"rollup": "^0.42.0"
"rollup": "^0.45.0"
},
"peerDependencies": {
"graphql": "^0.9.0 || ^0.10.0"
"graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0"
}
}
Loading

0 comments on commit 7fd462d

Please sign in to comment.