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

Conversation

apalm
Copy link
Contributor

@apalm apalm commented Oct 27, 2017

This PR adds support for babel-plugin-macros.

Usage:

import {graphql} from 'react-relay/macro';
// Or: 
// const {graphql} = require('react-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 #1968

Related: facebook/create-react-app#2730 (comment)

/cc @kentcdodds

exports[`BabelPluginRelayMacro 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).

@@ -0,0 +1 @@
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 👍

gulpfile.js Outdated
@@ -162,7 +162,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.

Copy link

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

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

This is looking great! I left a few comments.

Thanks so much for putting the work into it!

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

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 👍

@@ -0,0 +1 @@
module.exports = require('../../babel-plugin-relay/BabelPluginRelayMacro');

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 👍

parserOpts: {plugins: ['jsx']},
babelrc: false,
});
expect(code).toMatchSnapshot();

Choose a reason for hiding this comment

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

Have you considered using babel-plugin-tester? It reduces the amount of boilerplate and the snapshot is a bit more insightful. Here's an example with a macro and here are the snapshots.

});
}

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.

@@ -100,3 +100,11 @@ When compiling code for production deployment, the plugin can be configured to i
]
}
```

### Alternatives

Choose a reason for hiding this comment

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

If you want to, you could add the babel-macro badge:

Babel Macro

[![Babel Macro](https://img.shields.io/badge/babel--macro-%F0%9F%8E%A3-f5da55.svg?style=flat-square)](https://github.com/kentcdodds/babel-macros)

Copy link
Member

@kassens kassens left a comment

Choose a reason for hiding this comment

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

This is really cool, thanks for working on it!

Seems like it might actually be ready and no longer WIP?

});
}

module.exports = createMacro(BabelPluginRelayMacro);
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.

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

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

@apalm
Copy link
Contributor Author

apalm commented Oct 27, 2017

@kassens Thanks for looking!

Since it sounds like only Modern needs to be supported, I'll update BabelPluginRelay.md to note that this only works in Modern.

I presume your comment is referring to the haste option, and it doesn't need to be supported?

Did you have any opinions on testing? i.e. like using the fixtures in __tests__/fixtures-modern. Also, the current way of testing by importing from ../../react-relay/modern/ReactRelayGraphQL.macro feels iffy, since consumers would import from react-relay/macro, but not sure if there's a better way.

@DavidBabel
Copy link

Any status on this PR ?

@apalm
Copy link
Contributor Author

apalm commented Nov 13, 2017

Sorry for dropping the ball; been busy. I plan to update the PR either later this week or early next week.

package.json Outdated
@@ -21,6 +21,7 @@
"babel-core": "6.25.0",
"babel-eslint": "7.2.3",
"babel-generator": "^6.26.0",
"babel-macros": "1.2.0",

Choose a reason for hiding this comment

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

@kassens
Copy link
Member

kassens commented Dec 23, 2017

@apalm: I still think this would be awesome, do you want to continue this or have someone take over?

@apalm
Copy link
Contributor Author

apalm commented Dec 26, 2017

@kassens: Yes, I still want to continue this. Sorry again for dropping the ball.

With the latest commits, I:

  • Fixed merge conflicts
  • Changed from babel-macros -> babel-plugin-macros
  • Addressed a few review comments. I followed Kent's suggestion and used babel-plugin-tester, but if you're not keen on the extra dependency, it's easy to revert, as the change is in a separate commit.

Let me know if you need anything else from me.

@wtgtybhertgeghgtwtg
Copy link

Is it still a work in progress, then?

@wtgtybhertgeghgtwtg
Copy link

babel-plugin-macros support has landed in latest alpha for create-react-app: facebook/create-react-app#3675 (comment)

@alloy
Copy link
Contributor

alloy commented Jan 28, 2018

@apalm Your last comment makes it sound like this PR is no longer a WIP, is that the case? If so, please update the PR title.

@apalm apalm changed the title [WIP] Support babel-macros Support babel-plugin-macros Jan 28, 2018
@apalm
Copy link
Contributor Author

apalm commented Jan 28, 2018

@alloy Yes, that's correct. I've updated the title.

@alloy
Copy link
Contributor

alloy commented Jan 28, 2018

@kassens @jstejada Good to go?

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@jstejada has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@zachasme
Copy link

zachasme commented Jun 4, 2018

This is the last remaining blocker for using relay in CRA@next without ejecting.

@kassens
Copy link
Member

kassens commented Aug 8, 2018

Finally found some time to figure out what was wrong in the gulpfile and got a working CRA with Relay 🎉

I couldn't figure out how to push to this branch, so put up my commit with the fixes at kassens/relay@d7321f9e

The last things I'm not clear about:

First, I want to avoid a dependency from relay-runtime on the babel plugin, so I moved the macro into the babel plugin:

import graphql from "babel-plugin-relay/macro";

Is this weird? We could also move to a new package, maybe import graphql from 'relay.macro'?

Second, should babel-plugin-relay have some sort of dependency on babel-plugin-macros as there's a require in there?

@kentcdodds
Copy link

kentcdodds commented Aug 8, 2018

That's great news!

Is this weird?

Nope, not weird at all. I have several packages that do this.

We could also move to a new package, maybe import graphql from 'relay.macro'?

This is what I do. For example codegen.macro's entry file:

// the entire point of this package is to make it easier to use
// babel-plugin-codegen/macro
module.exports = require('babel-plugin-codegen/macro')

should babel-plugin-relay have some sort of dependency on babel-plugin-macros as there's a require in there?

Yes, if babel-plugin-relay publishes code that uses babel-plugin-macros then it should have babel-plugin-macros as a regular dependency.

@kassens
Copy link
Member

kassens commented Aug 8, 2018

@apalm want to merge the changes from kassens/relay@d7321f9e here? When I merge this it'll all be a single commit and you did most of the work :)

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

kassens has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@kassens
Copy link
Member

kassens commented Aug 8, 2018

Figured it out, hopefully not running into problems with the internal merge now!

@apalm
Copy link
Contributor Author

apalm commented Aug 8, 2018

@kassens Thank you for picking this back up (and for fixing the issues with the original approach 😅).

I think the docs still need updating though, per the changes you mentioned in #2171 (comment).

I was also able to confirm a working CRA locally using react-scripts@2.0.0-next.3e165448 and using import graphql from "babel-plugin-relay/macro" :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add support for babel-macros
8 participants