From f74387d268e0ec68f442cc8f813e053d92f00920 Mon Sep 17 00:00:00 2001 From: Andrew Palm Date: Mon, 13 Aug 2018 09:49:38 -0700 Subject: [PATCH] Support babel-plugin-macros (#2171) Summary: This PR adds support for [babel-plugin-macros](https://github.com/kentcdodds/babel-plugin-macros). Usage: ```js import graphql from 'babel-plugin-relay/macro'; // Or: // const graphql = require('babel-plugin-relay/macro'); ``` `graphql` is exported from both the `react-relay` and `relay-runtime` packages, but as I created this PR mostly in the interest of possible Create React App integration, I only added an export to `react-relay`. This PR currently only adds support for Relay Modern. I'm not sure if Compat and/or Classic should be supported? I currently only have a single basic test. I certainly could copy over the fixtures in `__tests__/fixtures-modern` and change the imports, although I'm not sure how beneficial that would be, as most of the logic is shared with `babel-plugin-relay`. Closes https://github.com/facebook/relay/issues/1968 Related: https://github.com/facebookincubator/create-react-app/issues/2730#issuecomment-313554085 /cc kentcdodds Pull Request resolved: https://github.com/facebook/relay/pull/2171 Reviewed By: jstejada Differential Revision: D6831205 Pulled By: kassens fbshipit-source-id: 704a239b45974359cc1dcecacd85efb4aeddeef5 --- docs/Introduction-InstallationAndSetup.md | 6 ++ gulpfile.js | 2 + package.json | 2 + .../BabelPluginRelay.macro.js | 31 ++++++++++ .../__tests__/BabelPluginRelay.macro-test.js | 42 +++++++++++++ .../BabelPluginRelay.macro-test.js.snap | 37 +++++++++++ packages/babel-plugin-relay/package.json | 1 + yarn.lock | 62 ++++++++++++++++++- 8 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 packages/babel-plugin-relay/BabelPluginRelay.macro.js create mode 100644 packages/babel-plugin-relay/__tests__/BabelPluginRelay.macro-test.js create mode 100644 packages/babel-plugin-relay/__tests__/__snapshots__/BabelPluginRelay.macro-test.js.snap diff --git a/docs/Introduction-InstallationAndSetup.md b/docs/Introduction-InstallationAndSetup.md index 9916ce33e8435..da1d5cd16d7f7 100644 --- a/docs/Introduction-InstallationAndSetup.md +++ b/docs/Introduction-InstallationAndSetup.md @@ -35,6 +35,12 @@ Babel's [documentation on this topic](https://babeljs.io/docs/plugins/#pluginpre See the [Migration Setup](./migration-setup.html) guide if upgrading an existing Relay app. +Alternatively, instead of using `babel-plugin-relay`, you can use Relay with [babel-plugin-macros](https://github.com/kentcdodds/babel-plugin-macros). After installing `babel-plugin-macros` and adding it to your Babel config: + +```javascript +const graphql = require('babel-plugin-relay/macro'); +``` + ## Set up relay-compiler Relay's ahead-of-time compilation requires the [Relay Compiler](./graphql-in-relay.html#relay-compiler.html), which you can install via `yarn` or `npm`: diff --git a/gulpfile.js b/gulpfile.js index a6033dc63c260..6053159c23d70 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -18,6 +18,7 @@ const babelOptions = require('./scripts/getBabelOptions')({ '@babel/parser': '@babel/parser', '@babel/types': '@babel/types', 'babel-core': 'babel-core', + 'babel-plugin-macros': 'babel-plugin-macros', 'babel-generator': 'babel-generator', 'babel-generator/lib/printer': 'babel-generator/lib/printer', 'babel-polyfill': 'babel-polyfill', @@ -153,6 +154,7 @@ const builds = [ package: 'babel-plugin-relay', exports: { index: 'BabelPluginRelay.js', + macro: 'BabelPluginRelay.macro.js', }, bundles: [ { diff --git a/package.json b/package.json index d3a3ed140e53d..00896ab3646ce 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,8 @@ "babel-cli": "6.24.1", "babel-core": "6.25.0", "babel-eslint": "9.0.0-beta.2", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-tester": "^5.0.0", "babel-plugin-transform-async-to-generator": "6.24.1", "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", "babel-plugin-transform-flow-strip-types": "6.22.0", diff --git a/packages/babel-plugin-relay/BabelPluginRelay.macro.js b/packages/babel-plugin-relay/BabelPluginRelay.macro.js new file mode 100644 index 0000000000000..05de4d06f331e --- /dev/null +++ b/packages/babel-plugin-relay/BabelPluginRelay.macro.js @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2013-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. + * + * @flow + * @format + */ + +'use strict'; + +const compileGraphQLTag = require('./compileGraphQLTag'); +const getValidGraphQLTag = require('./getValidGraphQLTag'); + +const {createMacro} = require('babel-plugin-macros'); + +function BabelPluginRelayMacro({references, state, babel}) { + const {types: t} = babel; + Object.keys(references).forEach(referenceKey => { + references[referenceKey].forEach(reference => { + const path = reference.parentPath; + const ast = getValidGraphQLTag(path); + if (ast) { + compileGraphQLTag(t, path, state, ast); + } + }); + }); +} + +module.exports = createMacro(BabelPluginRelayMacro); diff --git a/packages/babel-plugin-relay/__tests__/BabelPluginRelay.macro-test.js b/packages/babel-plugin-relay/__tests__/BabelPluginRelay.macro-test.js new file mode 100644 index 0000000000000..8ba0790f8a4fe --- /dev/null +++ b/packages/babel-plugin-relay/__tests__/BabelPluginRelay.macro-test.js @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2013-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. + * + * @format + * @emails oncall+relay + */ + +'use strict'; + +require('configureForRelayOSS'); + +const pluginTester = require('babel-plugin-tester'); +const plugin = require('babel-plugin-macros'); + +pluginTester({ + plugin, + snapshot: true, + title: 'BabelPluginRelayMacro', + babelOptions: {filename: __filename, parserOpts: {plugins: ['jsx']}}, + tests: { + works: ` + 'use strict'; + + const {graphql} = require('../BabelPluginRelay.macro'); + const ProfilePic = require('ProfilePic'); + + const ViewerQuery = graphql\` + query ViewerQuery($id: ID!, $scale: Float = 1.5) { + node(id: $id) { + ... on User { + id + ...ProfilePic_user + } + } + } + \`; + `, + }, +}); diff --git a/packages/babel-plugin-relay/__tests__/__snapshots__/BabelPluginRelay.macro-test.js.snap b/packages/babel-plugin-relay/__tests__/__snapshots__/BabelPluginRelay.macro-test.js.snap new file mode 100644 index 0000000000000..d6a0e40805ed2 --- /dev/null +++ b/packages/babel-plugin-relay/__tests__/__snapshots__/BabelPluginRelay.macro-test.js.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`BabelPluginRelayMacro works: works 1`] = ` +" +'use strict'; + +const {graphql} = require('../BabelPluginRelay.macro'); +const ProfilePic = require('ProfilePic'); + +const ViewerQuery = graphql\` + query ViewerQuery($id: ID!, $scale: Float = 1.5) { + node(id: $id) { + ... on User { + id + ...ProfilePic_user + } + } + } +\`; + + ↓ ↓ ↓ ↓ ↓ ↓ + +'use strict'; + +const ProfilePic = require('ProfilePic'); + +const ViewerQuery = function () { + const node = require('./__generated__/ViewerQuery.graphql'); + + if (node.hash && node.hash !== 'b046a97b7823510c05083ebb114377f4') { + console.error('The definition of \\\\'ViewerQuery\\\\' appears to have changed. Run \`relay-compiler\` to update the generated files to receive the expected data.'); + } + + return require('./__generated__/ViewerQuery.graphql'); +}; +" +`; diff --git a/packages/babel-plugin-relay/package.json b/packages/babel-plugin-relay/package.json index b08399b55d29c..8a9d75c62a851 100644 --- a/packages/babel-plugin-relay/package.json +++ b/packages/babel-plugin-relay/package.json @@ -13,6 +13,7 @@ "bugs": "https://github.com/facebook/relay/issues", "repository": "facebook/relay", "dependencies": { + "babel-plugin-macros": "^2.0.0", "babel-runtime": "^6.23.0", "babel-types": "^6.24.1" }, diff --git a/yarn.lock b/yarn.lock index b01a2e5fa9ffb..b64201efa6b72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -671,6 +671,12 @@ babel-plugin-jest-hoist@^23.0.1: version "23.0.1" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.0.1.tgz#eaa11c964563aea9c21becef2bdf7853f7f3c148" +babel-plugin-macros@^2.0.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.4.0.tgz#6c5f9836e1f6c0a9743b3bab4af29f73e437e544" + dependencies: + cosmiconfig "^5.0.5" + babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" @@ -695,6 +701,16 @@ babel-plugin-syntax-trailing-function-commas@^6.8.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" +babel-plugin-tester@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-tester/-/babel-plugin-tester-5.0.0.tgz#d3387860311cbd8353746d3a8aaba7ad2446e470" + dependencies: + common-tags "^1.4.0" + invariant "^2.2.2" + lodash.merge "^4.6.0" + path-exists "^3.0.0" + strip-indent "^2.0.0" + babel-plugin-transform-async-to-generator@6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" @@ -1358,6 +1374,12 @@ commander@^2.11.0, commander@^2.8.1: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" +common-tags@^1.4.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.6.0.tgz#788e4bcc582f16993e5b2c92f76b1ccb80731537" + dependencies: + babel-runtime "^6.26.0" + compare-versions@^3.1.0: version "3.3.0" resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.3.0.tgz#af93ea705a96943f622ab309578b9b90586f39c3" @@ -1423,6 +1445,14 @@ core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" +cosmiconfig@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.5.tgz#a809e3c2306891ce17ab70359dc8bdf661fe2cd0" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + create-react-class@^15.6.0: version "15.6.3" resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036" @@ -1713,7 +1743,7 @@ errno@^0.1.3: dependencies: prr "~1.0.1" -error-ex@^1.2.0: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" dependencies: @@ -2945,6 +2975,10 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -3507,6 +3541,13 @@ js-yaml@^3.11.0, js-yaml@^3.7.0: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^3.9.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -3550,6 +3591,10 @@ jsesc@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" @@ -3748,6 +3793,10 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" +lodash.merge@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" + lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" @@ -4394,6 +4443,13 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -5322,6 +5378,10 @@ strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"