From 7b278c16276faa47026cc6e44a55d5754c9119e5 Mon Sep 17 00:00:00 2001 From: petetnt Date: Tue, 23 Jan 2018 20:49:22 +0200 Subject: [PATCH 01/16] Add graphql loader to webpack config Signed-off-by: petetnt --- packages/react-scripts/config/webpack.config.dev.js | 7 +++++++ packages/react-scripts/config/webpack.config.prod.js | 7 +++++++ packages/react-scripts/package.json | 2 ++ 3 files changed, 16 insertions(+) diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index c07819594b0..48bcc2535cb 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -289,6 +289,13 @@ module.exports = { }, ], }, + // The graphql loader saves GraphQL ASTs processing time on client-side + // and enables queries to be separated from script over .graphql and .gql files. + { + test: /\.(graphql|gql)$/, + exclude: /node_modules/, + loader: 'graphql-tag/loader', + }, // "file" loader makes sure those assets get served by WebpackDevServer. // When you `import` an asset, you get its (virtual) filename. // In production, they would get copied to the `build` folder. diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index c2f8cc813f3..ffacf62fd73 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -331,6 +331,13 @@ module.exports = { }, ], }, + // The graphql loader saves GraphQL ASTs processing time on client-side + // and enables queries to be separated from script over .graphql and .gql files. + { + test: /\.(graphql|gql)$/, + exclude: /node_modules/, + loader: 'graphql-tag/loader', + }, // "file" loader makes sure assets end up in the `build` folder. // When you `import` an asset, you get its filename. // This loader doesn't use a "test" so it will catch all modules diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 7fa42331eff..37610b0c1a4 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -44,6 +44,8 @@ "extract-text-webpack-plugin": "3.0.2", "file-loader": "1.1.6", "fs-extra": "5.0.0", + "graphql": "^0.12.3", + "graphql-tag": "^2.6.1", "html-webpack-plugin": "2.30.1", "identity-obj-proxy": "3.0.0", "jest": "22.1.2", From 123e89ec5c3fd7243151df377a09a361dd296ec6 Mon Sep 17 00:00:00 2001 From: petetnt Date: Tue, 23 Jan 2018 22:29:27 +0200 Subject: [PATCH 02/16] Update README.md Signed-off-by: petetnt --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 698cf4fc3f2..98a683aedac 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ Your environment will have everything you need to build a modern single-page Rea * Autoprefixed CSS, so you don’t need `-webkit-` or other prefixes. * A fast interactive unit test runner with built-in support for coverage reporting. * A live development server that warns about common mistakes. -* A build script to bundle JS, CSS, and images for production, with hashes and sourcemaps. +* A build script to bundle JS, CSS, GraphQL files and images for production, with hashes and sourcemaps. * An offline-first [service worker](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers) and a [web app manifest](https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/), meeting all the [Progressive Web App](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app) criteria. * Hassle-free updates for the above tools with a single dependency. From c64c25c4901ef829146e25a131feab40f771f523 Mon Sep 17 00:00:00 2001 From: petetnt Date: Tue, 23 Jan 2018 22:30:09 +0200 Subject: [PATCH 03/16] Update react-scripts README.md Signed-off-by: petetnt --- packages/react-scripts/template/README.md | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 17a85d627f2..b4268a6985e 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -27,6 +27,7 @@ You can find the most recent version of this guide [here](https://github.com/fac - [Post-Processing CSS](#post-processing-css) - [Adding a CSS Preprocessor (Sass, Less etc.)](#adding-a-css-preprocessor-sass-less-etc) - [Adding Images, Fonts, and Files](#adding-images-fonts-and-files) +- [Adding GraphQL files](#adding-graphql-files) - [Using the `public` Folder](#using-the-public-folder) - [Changing the HTML](#changing-the-html) - [Adding Assets Outside of the Module System](#adding-assets-outside-of-the-module-system) @@ -687,6 +688,30 @@ Now running `npm start` and `npm run build` also builds Sass files. `node-sass-chokidar` is used here as it addresses these issues. +## Adding GraphQL files + +If you are using GraphQL, you can **import a your GraphQL queries directly in a JavaScript module**. + +By preprocessing the GraphQL queries by importing them instead of using (for example) a [template tag](https://github.com/apollographql/graphql-tag), you save GraphQL ASTs processing time on client-side and enable queries to be separated from script over `.graphql` or `.gql` files. + +Here is an example: + +```js +// query.graphql +{ + githubStats(repository: "facebook/react") { + stars + } +} + +import query from './query.graphql'; + +console.log(query); +// { +// "kind": "Document", +// ... +``` + ## Adding Images, Fonts, and Files With Webpack, using static assets like images and fonts works similarly to CSS. From 53e215ff152300583148102a3e880bb49d7ff6dd Mon Sep 17 00:00:00 2001 From: petetnt Date: Tue, 23 Jan 2018 22:55:20 +0200 Subject: [PATCH 04/16] Add graphql jest transform Signed-off-by: petetnt --- .../react-scripts/config/jest/graphqlTransform.js | 13 +++++++++++++ packages/react-scripts/package.json | 1 + .../react-scripts/scripts/utils/createJestConfig.js | 5 ++++- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 packages/react-scripts/config/jest/graphqlTransform.js diff --git a/packages/react-scripts/config/jest/graphqlTransform.js b/packages/react-scripts/config/jest/graphqlTransform.js new file mode 100644 index 00000000000..e77172819fe --- /dev/null +++ b/packages/react-scripts/config/jest/graphqlTransform.js @@ -0,0 +1,13 @@ +// @remove-on-eject-begin +/** + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +// @remove-on-eject-end +'use strict'; + +const graphqlTransform = require('jest-transform-graphql'); + +module.exports = graphqlTransform; diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 37610b0c1a4..a40d7ba24db 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -49,6 +49,7 @@ "html-webpack-plugin": "2.30.1", "identity-obj-proxy": "3.0.0", "jest": "22.1.2", + "jest-transform-graphql": "^2.1.0", "object-assign": "4.1.1", "postcss-flexbugs-fixes": "3.2.0", "postcss-loader": "2.0.10", diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js index cdea70699c0..485766b8e23 100644 --- a/packages/react-scripts/scripts/utils/createJestConfig.js +++ b/packages/react-scripts/scripts/utils/createJestConfig.js @@ -35,7 +35,10 @@ module.exports = (resolve, rootDir, isEjecting) => { ? '/node_modules/babel-jest' : resolve('config/jest/babelTransform.js'), '^.+\\.css$': resolve('config/jest/cssTransform.js'), - '^(?!.*\\.(js|jsx|mjs|css|json)$)': resolve( + '^.+\\.(gql|graphql)$': isEjecting + ? '/node_modules/jest-transform-graphql' + : resolve('config/jest/graphqlTransform.js'), + '^(?!.*\\.(js|jsx|mjs|css|json|graphql|gql)$)': resolve( 'config/jest/fileTransform.js' ), }, From d1dd2a8bff3ee8fca5ce0a6b044a336df50a548c Mon Sep 17 00:00:00 2001 From: petetnt Date: Tue, 23 Jan 2018 23:57:19 +0200 Subject: [PATCH 05/16] Add integration tests, pin versions in package.json Signed-off-by: petetnt --- .../kitchensink/integration/webpack.test.js | 15 +++++++++++++++ .../fixtures/kitchensink/src/App.js | 11 ++++++++--- .../src/features/webpack/GraphQLInclusion.js | 17 +++++++++++++++++ .../features/webpack/GraphQLInclusion.test.js | 17 +++++++++++++++++ .../src/features/webpack/assets/graphql.gql | 5 +++++ .../src/features/webpack/assets/graphql.graphql | 5 +++++ packages/react-scripts/package.json | 6 +++--- 7 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.gql create mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.graphql diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 06ec83602f3..3271c0ce63c 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -31,6 +31,21 @@ describe('Integration', () => { ); }); + it('graphql files inclusion', async () => { + const doc = await initDOM('graphql-inclusion'); + const children = doc.getElementById('graphql-inclusion').children; + + // .graphql + expect(children[0].textContent.replace(/\s/g, '')).to.match( + '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":41}}' + ); + + // .gql + expect(children[1].textContent.replace(/\s/g, '')).to.match( + '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":41}}' + ); + }); + it('image inclusion', async () => { const doc = await initDOM('image-inclusion'); diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.js b/packages/react-scripts/fixtures/kitchensink/src/App.js index d1affb48af9..03b2044b972 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/App.js +++ b/packages/react-scripts/fixtures/kitchensink/src/App.js @@ -82,9 +82,9 @@ class App extends Component { ); break; case 'css-modules-inclusion': - import( - './features/webpack/CssModulesInclusion' - ).then(f => this.setFeature(f.default)); + import('./features/webpack/CssModulesInclusion').then(f => + this.setFeature(f.default) + ); break; case 'custom-interpolation': import('./features/syntax/CustomInterpolation').then(f => @@ -111,6 +111,11 @@ class App extends Component { this.setFeature(f.default) ); break; + case 'graphql-inclusion': + import('./features/webpack/GraphQLInclusion').then(f => + this.setFeature(f.default) + ); + break; case 'image-inclusion': import('./features/webpack/ImageInclusion').then(f => this.setFeature(f.default) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.js new file mode 100644 index 00000000000..52784ce4545 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.js @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import A from './assets/graphql.graphql'; +import B from './assets/graphql.gql'; + +export default () => ( +

+ {JSON.stringify(A)} + {JSON.stringify(B)} +

+); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.test.js new file mode 100644 index 00000000000..914ce241bdd --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.test.js @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import GraphQLInclusion from './GraphQLInclusion'; + +describe('graphql files inclusion', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.gql b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.gql new file mode 100644 index 00000000000..6125e344f55 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.gql @@ -0,0 +1,5 @@ +{ + test(test: "test") { + test + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.graphql b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.graphql new file mode 100644 index 00000000000..6125e344f55 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.graphql @@ -0,0 +1,5 @@ +{ + test(test: "test") { + test + } +} diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index a40d7ba24db..ef0df80e0d0 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -44,12 +44,12 @@ "extract-text-webpack-plugin": "3.0.2", "file-loader": "1.1.6", "fs-extra": "5.0.0", - "graphql": "^0.12.3", - "graphql-tag": "^2.6.1", + "graphql": "0.12.3", + "graphql-tag": "2.6.1", "html-webpack-plugin": "2.30.1", "identity-obj-proxy": "3.0.0", "jest": "22.1.2", - "jest-transform-graphql": "^2.1.0", + "jest-transform-graphql": "2.1.0", "object-assign": "4.1.1", "postcss-flexbugs-fixes": "3.2.0", "postcss-loader": "2.0.10", From f32d3fd93364bd884342aeba4a21fc44bad24cb2 Mon Sep 17 00:00:00 2001 From: petetnt Date: Wed, 24 Jan 2018 10:39:04 +0200 Subject: [PATCH 06/16] Tests expect regexp matchers Signed-off-by: petetnt --- .../fixtures/kitchensink/integration/webpack.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 3271c0ce63c..1ddfa31cbad 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -37,12 +37,12 @@ describe('Integration', () => { // .graphql expect(children[0].textContent.replace(/\s/g, '')).to.match( - '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":41}}' + /^{"kind":"Document","definitions":\[{"kind":"OperationDefinition","operation":"query","variableDefinitions":\[],"directives":\[\],"selectionSet":{"kind":"SelectionSet","selections":\[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":\[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}\],"directives":\[\],"selectionSet":{"kind":"SelectionSet","selections":\[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":\[\],"directives":\[\]}\]}}\]}}\],"loc":{"start":0,"end":41}}$/ ); // .gql expect(children[1].textContent.replace(/\s/g, '')).to.match( - '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":41}}' + /^{"kind":"Document","definitions":\[{"kind":"OperationDefinition","operation":"query","variableDefinitions":\[],"directives":\[\],"selectionSet":{"kind":"SelectionSet","selections":\[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":\[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}\],"directives":\[\],"selectionSet":{"kind":"SelectionSet","selections":\[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":\[\],"directives":\[\]}\]}}\]}}\],"loc":{"start":0,"end":41}}$/ ); }); From 3a14cd1c08b462c713c35632a649f54f44d93626 Mon Sep 17 00:00:00 2001 From: petetnt Date: Wed, 24 Jan 2018 11:02:51 +0200 Subject: [PATCH 07/16] Use strict equal test instead Signed-off-by: petetnt --- .../fixtures/kitchensink/integration/webpack.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 1ddfa31cbad..69b699a9832 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -36,13 +36,13 @@ describe('Integration', () => { const children = doc.getElementById('graphql-inclusion').children; // .graphql - expect(children[0].textContent.replace(/\s/g, '')).to.match( - /^{"kind":"Document","definitions":\[{"kind":"OperationDefinition","operation":"query","variableDefinitions":\[],"directives":\[\],"selectionSet":{"kind":"SelectionSet","selections":\[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":\[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}\],"directives":\[\],"selectionSet":{"kind":"SelectionSet","selections":\[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":\[\],"directives":\[\]}\]}}\]}}\],"loc":{"start":0,"end":41}}$/ + expect(children[0].textContent.replace(/\s/g, '')).to.equal( + '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":40,"source":{"body":"{\\\\ntest(test:\\\\"test\\\\"){\\\\ntest\\\\n}\\\\n}\\\\n","name":"GraphQLrequest","locationOffset":{"line":1,"column":1}}}}' ); // .gql - expect(children[1].textContent.replace(/\s/g, '')).to.match( - /^{"kind":"Document","definitions":\[{"kind":"OperationDefinition","operation":"query","variableDefinitions":\[],"directives":\[\],"selectionSet":{"kind":"SelectionSet","selections":\[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":\[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}\],"directives":\[\],"selectionSet":{"kind":"SelectionSet","selections":\[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":\[\],"directives":\[\]}\]}}\]}}\],"loc":{"start":0,"end":41}}$/ + expect(children[1].textContent.replace(/\s/g, '')).to.equal( + '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":40,"source":{"body":"{\\\\ntest(test:\\\\"test\\\\"){\\\\ntest\\\\n}\\\\n}\\\\n","name":"GraphQLrequest","locationOffset":{"line":1,"column":1}}}}' ); }); From 435ece053f2c3a75f8292860f9c9189c13e65aa8 Mon Sep 17 00:00:00 2001 From: petetnt Date: Wed, 24 Jan 2018 11:20:09 +0200 Subject: [PATCH 08/16] Escaping is hard Signed-off-by: petetnt --- .../fixtures/kitchensink/integration/webpack.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 69b699a9832..38b02cf0ba3 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -37,12 +37,12 @@ describe('Integration', () => { // .graphql expect(children[0].textContent.replace(/\s/g, '')).to.equal( - '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":40,"source":{"body":"{\\\\ntest(test:\\\\"test\\\\"){\\\\ntest\\\\n}\\\\n}\\\\n","name":"GraphQLrequest","locationOffset":{"line":1,"column":1}}}}' + '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":40,"source":{"body":"{\\ntest(test:\\"test\\"){\\ntest\\n}\\n}\\n","name":"GraphQLrequest","locationOffset":{"line":1,"column":1}}}}' ); // .gql expect(children[1].textContent.replace(/\s/g, '')).to.equal( - '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":40,"source":{"body":"{\\\\ntest(test:\\\\"test\\\\"){\\\\ntest\\\\n}\\\\n}\\\\n","name":"GraphQLrequest","locationOffset":{"line":1,"column":1}}}}' + '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":40,"source":{"body":"{\\ntest(test:\\"test\\"){\\ntest\\n}\\n}\\n","name":"GraphQLrequest","locationOffset":{"line":1,"column":1}}}}' ); }); From 0860029585f1708ef91d479ff2ed36db51b0b32a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pete=20Nyk=C3=A4nen?= Date: Wed, 24 Jan 2018 23:26:44 +0200 Subject: [PATCH 09/16] Add comment for signifying a different file --- packages/react-scripts/template/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index b4268a6985e..4722d3d0468 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -704,6 +704,8 @@ Here is an example: } } +// foo.js + import query from './query.graphql'; console.log(query); From eeed28f86f2003e6f409ac0c33a581156cbb94e5 Mon Sep 17 00:00:00 2001 From: Ian Sutherland Date: Fri, 2 Feb 2018 14:12:28 -0700 Subject: [PATCH 10/16] Update docs --- README.md | 2 +- packages/react-scripts/template/README.md | 52 +++++++++++------------ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 98a683aedac..698cf4fc3f2 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ Your environment will have everything you need to build a modern single-page Rea * Autoprefixed CSS, so you don’t need `-webkit-` or other prefixes. * A fast interactive unit test runner with built-in support for coverage reporting. * A live development server that warns about common mistakes. -* A build script to bundle JS, CSS, GraphQL files and images for production, with hashes and sourcemaps. +* A build script to bundle JS, CSS, and images for production, with hashes and sourcemaps. * An offline-first [service worker](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers) and a [web app manifest](https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/), meeting all the [Progressive Web App](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app) criteria. * Hassle-free updates for the above tools with a single dependency. diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 4722d3d0468..5ec8d8f7078 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -688,32 +688,6 @@ Now running `npm start` and `npm run build` also builds Sass files. `node-sass-chokidar` is used here as it addresses these issues. -## Adding GraphQL files - -If you are using GraphQL, you can **import a your GraphQL queries directly in a JavaScript module**. - -By preprocessing the GraphQL queries by importing them instead of using (for example) a [template tag](https://github.com/apollographql/graphql-tag), you save GraphQL ASTs processing time on client-side and enable queries to be separated from script over `.graphql` or `.gql` files. - -Here is an example: - -```js -// query.graphql -{ - githubStats(repository: "facebook/react") { - stars - } -} - -// foo.js - -import query from './query.graphql'; - -console.log(query); -// { -// "kind": "Document", -// ... -``` - ## Adding Images, Fonts, and Files With Webpack, using static assets like images and fonts works similarly to CSS. @@ -755,6 +729,32 @@ Please be advised that this is also a custom feature of Webpack. **It is not required for React** but many people enjoy it (and React Native uses a similar mechanism for images).
An alternative way of handling static assets is described in the next section. +## Adding GraphQL files + +If you are using GraphQL, you can **`import` GraphQL files in a JavaScript module**. + +By importing GraphQL queries instead of using a [template tag](https://github.com/apollographql/graphql-tag), they are preprocessed at build time. This eliminates the need to process them on the client at run time. It also allows you to separate your GraphQL queries from your code. You can put a GraphQL query in a file with a `.graphql` or `.gql` extension. + +Here is an example: + +```js +// query.graphql +{ + githubStats(repository: "facebook/react") { + stars + } +} + +// foo.js + +import query from './query.graphql'; + +console.log(query); +// { +// "kind": "Document", +// ... +``` + ## Using the `public` Folder >Note: this feature is available with `react-scripts@0.5.0` and higher. From e68515d99392e87247e7852c769a43c26114097f Mon Sep 17 00:00:00 2001 From: Ian Sutherland Date: Fri, 2 Feb 2018 14:47:00 -0700 Subject: [PATCH 11/16] Fix jest config --- packages/react-scripts/scripts/utils/createJestConfig.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js index f11e371bfa4..39d7ff34396 100644 --- a/packages/react-scripts/scripts/utils/createJestConfig.js +++ b/packages/react-scripts/scripts/utils/createJestConfig.js @@ -38,9 +38,7 @@ module.exports = (resolve, rootDir, srcRoots) => { transform: { '^.+\\.(js|jsx|mjs)$': resolve('config/jest/babelTransform.js'), '^.+\\.css$': resolve('config/jest/cssTransform.js'), - '^.+\\.(gql|graphql)$': isEjecting - ? '/node_modules/jest-transform-graphql' - : resolve('config/jest/graphqlTransform.js'), + '^.+\\.(gql|graphql)$': resolve('config/jest/graphqlTransform.js'), '^(?!.*\\.(js|jsx|mjs|css|json|graphql|gql)$)': resolve( 'config/jest/fileTransform.js' ), From 786ee4a291116e6fd6e321e9110cf35bf80bb6cb Mon Sep 17 00:00:00 2001 From: Ian Sutherland Date: Fri, 2 Feb 2018 15:39:36 -0700 Subject: [PATCH 12/16] Remove node_modules exclusion --- packages/react-scripts/config/webpack.config.dev.js | 1 - packages/react-scripts/config/webpack.config.prod.js | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index 8c121a59d23..f79a64756f7 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -281,7 +281,6 @@ module.exports = { // The GraphQL loader preprocesses GraphQL queries in .graphql and .gql files. { test: /\.(graphql|gql)$/, - exclude: /node_modules/, loader: 'graphql-tag/loader', }, // "file" loader makes sure those assets get served by WebpackDevServer. diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 472bc94b458..57044a99045 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -323,7 +323,6 @@ module.exports = { // The GraphQL loader preprocesses GraphQL queries in .graphql and .gql files. { test: /\.(graphql|gql)$/, - exclude: /node_modules/, loader: 'graphql-tag/loader', }, // "file" loader makes sure assets end up in the `build` folder. From 51984964d5f9cc9cbfb3571374947f050fd3d8b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pete=20Nyk=C3=A4nen?= Date: Sat, 3 Feb 2018 16:37:10 +0200 Subject: [PATCH 13/16] Update README.md --- packages/react-scripts/template/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index ef10a0c7666..fcfed2303a3 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -732,6 +732,8 @@ An alternative way of handling static assets is described in the next section. ## Adding GraphQL files +> Note: this feature is available with react-scripts@2.0.0 and higher. + If you are using GraphQL, you can **`import` GraphQL files in a JavaScript module**. By importing GraphQL queries instead of using a [template tag](https://github.com/apollographql/graphql-tag), they are preprocessed at build time. This eliminates the need to process them on the client at run time. It also allows you to separate your GraphQL queries from your code. You can put a GraphQL query in a file with a `.graphql` or `.gql` extension. From ce2e153dbc9e89855262580e469878fa3f54912d Mon Sep 17 00:00:00 2001 From: petetnt Date: Sat, 3 Feb 2018 16:44:31 +0200 Subject: [PATCH 14/16] Inline graphql jest transform Signed-off-by: petetnt --- packages/react-scripts/config/jest/graphqlTransform.js | 8 ++++++-- packages/react-scripts/package.json | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/react-scripts/config/jest/graphqlTransform.js b/packages/react-scripts/config/jest/graphqlTransform.js index e77172819fe..6954caeb413 100644 --- a/packages/react-scripts/config/jest/graphqlTransform.js +++ b/packages/react-scripts/config/jest/graphqlTransform.js @@ -8,6 +8,10 @@ // @remove-on-eject-end 'use strict'; -const graphqlTransform = require('jest-transform-graphql'); +const loader = require('graphql-tag/loader'); -module.exports = graphqlTransform; +module.exports = { + process(src) { + return loader.call({ cacheable() {} }, src); + }, +}; diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 771f6dfea45..d9e904d3ad9 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -52,7 +52,6 @@ "html-webpack-plugin": "2.30.1", "identity-obj-proxy": "3.0.0", "jest": "22.1.2", - "jest-transform-graphql": "2.1.0", "object-assign": "4.1.1", "postcss-flexbugs-fixes": "3.2.0", "postcss-loader": "2.0.10", From 39d39bcc57650c3db27394785e0c45e2c8be877d Mon Sep 17 00:00:00 2001 From: petetnt Date: Sat, 3 Feb 2018 17:08:12 +0200 Subject: [PATCH 15/16] Update copyright header Signed-off-by: petetnt --- packages/react-scripts/config/jest/graphqlTransform.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-scripts/config/jest/graphqlTransform.js b/packages/react-scripts/config/jest/graphqlTransform.js index 6954caeb413..5b70f07d6f2 100644 --- a/packages/react-scripts/config/jest/graphqlTransform.js +++ b/packages/react-scripts/config/jest/graphqlTransform.js @@ -1,6 +1,7 @@ // @remove-on-eject-begin /** * Copyright (c) 2018-present, Facebook, Inc. + * Copyright (c) 2016 Remind * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. From b356d27a9471b533544de46ae2874e53bddce714 Mon Sep 17 00:00:00 2001 From: petetnt Date: Sat, 3 Feb 2018 17:25:44 +0200 Subject: [PATCH 16/16] Use .graphql extension only Signed-off-by: petetnt --- packages/react-scripts/config/webpack.config.dev.js | 4 ++-- packages/react-scripts/config/webpack.config.prod.js | 4 ++-- .../fixtures/kitchensink/integration/webpack.test.js | 5 ----- .../kitchensink/src/features/webpack/GraphQLInclusion.js | 2 -- .../kitchensink/src/features/webpack/assets/graphql.gql | 5 ----- packages/react-scripts/scripts/utils/createJestConfig.js | 4 ++-- packages/react-scripts/template/README.md | 2 +- 7 files changed, 7 insertions(+), 19 deletions(-) delete mode 100644 packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.gql diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index f79a64756f7..398b8bf53b7 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -278,9 +278,9 @@ module.exports = { }, ], }, - // The GraphQL loader preprocesses GraphQL queries in .graphql and .gql files. + // The GraphQL loader preprocesses GraphQL queries in .graphql files. { - test: /\.(graphql|gql)$/, + test: /\.(graphql)$/, loader: 'graphql-tag/loader', }, // "file" loader makes sure those assets get served by WebpackDevServer. diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 57044a99045..7b73dd787cd 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -320,9 +320,9 @@ module.exports = { ), // Note: this won't work without `new ExtractTextPlugin()` in `plugins`. }, - // The GraphQL loader preprocesses GraphQL queries in .graphql and .gql files. + // The GraphQL loader preprocesses GraphQL queries in .graphql files. { - test: /\.(graphql|gql)$/, + test: /\.(graphql)$/, loader: 'graphql-tag/loader', }, // "file" loader makes sure assets end up in the `build` folder. diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index dfa636ff606..bba497c49f3 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -39,11 +39,6 @@ describe('Integration', () => { expect(children[0].textContent.replace(/\s/g, '')).to.equal( '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":40,"source":{"body":"{\\ntest(test:\\"test\\"){\\ntest\\n}\\n}\\n","name":"GraphQLrequest","locationOffset":{"line":1,"column":1}}}}' ); - - // .gql - expect(children[1].textContent.replace(/\s/g, '')).to.equal( - '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":40,"source":{"body":"{\\ntest(test:\\"test\\"){\\ntest\\n}\\n}\\n","name":"GraphQLrequest","locationOffset":{"line":1,"column":1}}}}' - ); }); it('image inclusion', async () => { diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.js index 52784ce4545..728b7a2847d 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/GraphQLInclusion.js @@ -7,11 +7,9 @@ import React from 'react'; import A from './assets/graphql.graphql'; -import B from './assets/graphql.gql'; export default () => (

{JSON.stringify(A)} - {JSON.stringify(B)}

); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.gql b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.gql deleted file mode 100644 index 6125e344f55..00000000000 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/graphql.gql +++ /dev/null @@ -1,5 +0,0 @@ -{ - test(test: "test") { - test - } -} diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js index 39d7ff34396..593d17090a7 100644 --- a/packages/react-scripts/scripts/utils/createJestConfig.js +++ b/packages/react-scripts/scripts/utils/createJestConfig.js @@ -38,8 +38,8 @@ module.exports = (resolve, rootDir, srcRoots) => { transform: { '^.+\\.(js|jsx|mjs)$': resolve('config/jest/babelTransform.js'), '^.+\\.css$': resolve('config/jest/cssTransform.js'), - '^.+\\.(gql|graphql)$': resolve('config/jest/graphqlTransform.js'), - '^(?!.*\\.(js|jsx|mjs|css|json|graphql|gql)$)': resolve( + '^.+\\.(graphql)$': resolve('config/jest/graphqlTransform.js'), + '^(?!.*\\.(js|jsx|mjs|css|json|graphql)$)': resolve( 'config/jest/fileTransform.js' ), }, diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index fcfed2303a3..2c533d49687 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -736,7 +736,7 @@ An alternative way of handling static assets is described in the next section. If you are using GraphQL, you can **`import` GraphQL files in a JavaScript module**. -By importing GraphQL queries instead of using a [template tag](https://github.com/apollographql/graphql-tag), they are preprocessed at build time. This eliminates the need to process them on the client at run time. It also allows you to separate your GraphQL queries from your code. You can put a GraphQL query in a file with a `.graphql` or `.gql` extension. +By importing GraphQL queries instead of using a [template tag](https://github.com/apollographql/graphql-tag), they are preprocessed at build time. This eliminates the need to process them on the client at run time. It also allows you to separate your GraphQL queries from your code. You can put a GraphQL query in a file with a `.graphql` extension. Here is an example: