Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support babel-plugin-macros #2171

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/Introduction-InstallationAndSetup.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ Babel's [documentation on this topic](https://babeljs.io/docs/plugins/#plugin-pr

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('react-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`:
Expand Down
3 changes: 2 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ const builds = [
exports: {
classic: 'ReactRelayClassicExports.js',
compat: 'ReactRelayCompatPublic.js',
index: 'ReactRelayPublic.js'
index: 'ReactRelayPublic.js',
macro: 'ReactRelayGraphQL.macro.js'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This outputs macro.js in dist/react-relay.

},
bundles: [
{
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
"babel-core": "6.25.0",
"babel-eslint": "7.2.3",
"babel-generator": "^6.26.0",
"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",
Expand Down
31 changes: 31 additions & 0 deletions packages/babel-plugin-relay/BabelPluginRelayMacro.js
Original file line number Diff line number Diff line change
@@ -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.
*
* @providesModule BabelPluginRelayMacro
* @flow
* @format
*/

'use strict';

const {createMacro} = require('babel-plugin-macros');
const compileGraphQLTag = require('./compileGraphQLTag');
const getValidGraphQLTag = require('./getValidGraphQLTag');

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);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like babel-plugin-relay is configurable. Part of the point of using the macro is so people don't need to update the babel configuration (so they can use it with create-react-app). However it is still handy to be able to configure specific plugins, so babel-macros has an experimental config feature. Learn about config.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the pointer. I didn't address this yet, as most of the options only pertain to Compat and Classic. Maybe @gaearon can help answer whether Compat and Classic should be supported?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If configuration is an edge case, I'd suggest omitting it for now. That's something that can be added later and I think it's better to not slow down the merge-ability of this PR for something that not many folks will need/use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we would want to support classic and compat for anything new. The rest of the options are only to allow us to use the same plugin internally at FB and shouldn't be needed in OSS.

Original file line number Diff line number Diff line change
@@ -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('../../react-relay/modern/ReactRelayGraphQL.macro');
const CompatProfilePic = require('CompatProfilePic');

const CompatViewerQuery = graphql\`
query CompatViewerQuery($id: ID!, $scale: Float = 1.5) {
node(id: $id) {
... on User {
id
...CompatProfilePic_user
}
}
}
\`;
`,
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`BabelPluginRelayMacro works: works 1`] = `
"
'use strict';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike in babel-plugin-relay, the import is not currently retained. I'm not sure if that's acceptable? AFAIK the import is retained with babel-plugin-relay only for the "unexpected invocation at runtime" warning (someone correct me if I'm wrong).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the import needs to be retained (or replaced with something else) then your macros can get the Program node from the state that's passed in and you can unshift an import yourself 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import is not needed in Modern (classic pulls some runtime helpers from it).

const {graphql} = require('../../react-relay/modern/ReactRelayGraphQL.macro');
const CompatProfilePic = require('CompatProfilePic');

const CompatViewerQuery = graphql\`
query CompatViewerQuery($id: ID!, $scale: Float = 1.5) {
node(id: $id) {
... on User {
id
...CompatProfilePic_user
}
}
}
\`;

↓ ↓ ↓ ↓ ↓ ↓

'use strict';

const CompatProfilePic = require('CompatProfilePic');

const CompatViewerQuery = function () {
const node = require('./__generated__/CompatViewerQuery.graphql');

if (node.hash && node.hash !== '42a62b166f34144936e64b3c65e42c4d') {
console.error('The definition of \\\\'CompatViewerQuery\\\\' appears to have changed. Run \`relay-compiler\` to update the generated files to receive the expected data.');
}

return require('./__generated__/CompatViewerQuery.graphql');
};
"
`;
5 changes: 5 additions & 0 deletions packages/react-relay/modern/ReactRelayGraphQL.macro.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// This module is named the way it is because babel-plugin-macros requires
// the source string to match the regex /[./]macro(\.js)?$/, and
// this module is imported in the test suite.

module.exports = require('../../babel-plugin-relay/BabelPluginRelayMacro');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module is named the way it is because babel-macros requires the source string to match the regex /[./]macro(\.js)?$/, and I import this module in the test suite.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to add that as a comment in the file 👍

57 changes: 55 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,12 @@ babel-plugin-jest-hoist@^22.0.3:
version "22.0.3"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.0.3.tgz#62cde5fe962fd41ae89c119f481ca5cd7dd48bb4"

babel-plugin-macros@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.0.0.tgz#fd3aee135f7dec0b82898b7c8f1aed6fa75f9af9"
dependencies:
cosmiconfig "3.1.0"

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"
Expand All @@ -537,6 +543,16 @@ babel-plugin-syntax-trailing-function-commas@^6.5.0, babel-plugin-syntax-trailin
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"
Expand Down Expand Up @@ -1207,6 +1223,12 @@ commander@^2.8.1:
version "2.11.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"

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"

component-emitter@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
Expand Down Expand Up @@ -1271,6 +1293,15 @@ 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@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-3.1.0.tgz#640a94bf9847f321800403cd273af60665c73397"
dependencies:
is-directory "^0.3.1"
js-yaml "^3.9.0"
parse-json "^3.0.0"
require-from-string "^2.0.1"

create-react-class@^15.6.0:
version "15.6.0"
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4"
Expand Down Expand Up @@ -1551,7 +1582,7 @@ errno@^0.1.3:
dependencies:
prr "~0.0.0"

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:
Expand Down Expand Up @@ -2783,6 +2814,10 @@ is-descriptor@^1.0.0:
is-data-descriptor "^0.1.4"
kind-of "^5.0.0"

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"
Expand Down Expand Up @@ -3309,7 +3344,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"

js-yaml@^3.7.0, js-yaml@^3.9.1:
js-yaml@^3.7.0, js-yaml@^3.9.0, js-yaml@^3.9.1:
version "3.10.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
dependencies:
Expand Down Expand Up @@ -3572,6 +3607,10 @@ lodash.mapvalues@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c"

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"
Expand Down Expand Up @@ -4154,6 +4193,12 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"

parse-json@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-3.0.0.tgz#fa6f47b18e23826ead32f263e744d0e1e847fb13"
dependencies:
error-ex "^1.3.1"

parse-passwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
Expand Down Expand Up @@ -4610,6 +4655,10 @@ require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"

require-from-string@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.1.tgz#c545233e9d7da6616e9d59adfb39fc9f588676ff"

require-main-filename@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
Expand Down Expand Up @@ -5072,6 +5121,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:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
Expand Down