-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Using Relay without Babel #828
Comments
👍 . I was also in same situation few months back , for now i am using macros to fire up relay-babel-plugin and then passing generated string to I'll love to see no babel dependency in future !.. :) |
Great questions! And thanks, @chandu0101, for following up with your approach.
This gets at why the plugin is necessary in the first place. Relay needs information from the GraphQL schema in order to interpret queries correctly. Examples include knowing the types of all fragments and fields, and being able to distinguish whether That said, we've discussed the idea of a schema-less Relay in which the queries themselves were simple objects, and any schema-level metadata was encoded in a composing layer (technically the queries are simple objects, but there's enough metadata that they aren't fun to write by hand). If that sounds vague, it is. tl;dr we're open to this idea but for the foreseeable future we're likely to continue using the plugin.
We don't currently use Relay with any compile-to-JS languages internally, so the core team is not likely to work on this directly. However, we are open to making changes to support using Relay in these languages. The best bet might be to submit a PR that changes the plugin to work with your language so we can discuss something concrete. If you're interested in working on this, note that we've tried to structure the plugin in a way that most of the babel-specific code is in |
@domkm have you seen that https://github.com/apollostack/relay-runtime-query ? Hope it helps. |
Currently working on improving that! My goal is to have exactly the thing requested above - a Relay client that can connect to any server at runtime, and still does query validation, etc. I think I'm pretty close, just need to improve things so that all of the Relay tests pass. |
Darn, looks like this commit in Relay 0.7.1 changed the API between the plugin and runtime: 6a1fdc9 Looks like there is an expectation that the version of the Babel plugin will always exactly match the Relay runtime version, so it could be really hard to make sure the tool I built above will work with new versions without some cooperation with the Relay team, or a more stable way to generate a working query AST. |
@stubailo Yes - as we iterate on Relay we often need to adjust the plugin to provide more/less/different information about the queries. The commit you linked is a perfect example, where we needed a stable identifier for a fragment at build time. We expect to continue iterating on the plugin for the foreseeable future, so the best bet here is to reuse parts of the plugin.
We're happy to support changes that would allow reuse of the portion of the plugin that transforms source GraphQL to JS code outside of the babel plugin. How about sending a pull request that demonstrates what changes you'd need in |
Sounds great - I'll try to get together a PR soon, I don't think it will be a big problem because the Babel AST very closely matches the actual data structure (to the point where I was able to mock Babel in the package above to actually get the right data). In the meanwhile, I've updated my NPM package to work with Relay 0.7.1! |
Sorry for dropping out. I've been using Relay via Babel and Webpack for the past few weeks since I needed to be immediately productive and I wanted to understand Relay better. However, I am still very interested in making Relay work with ClojureScript. After working with Relay and understanding it better, I am no longer interested in a client-side only version. Instead, I think it would be fairly easy to make Relay work with ClojureScript during the build process in a similar way to how it works with JavaScript and Babel. I think the only thing I need is a portable JavaScript function that, given a |
Yup, this is the direction that we recommend and are able to support (see my comments above). The only caveat is that the plugin replaces At this point I believe we have consensus on the high-level approach; feel free to submit a PR and we can discuss specifics there. |
Thanks, @josephsavona. After looking through the code and discussing this with @stubailo in Slack, it seems quite a bit more complicated than I hoped, in large part due to my lack of familiarity with Babel, Flow, and the rest of the modern JS ecosystem. I'll try to get to it eventually, though I hope that someone who is familiar with this and can knock it out it a couple hours will do so. For what it's worth, this seems like a crucial step in growing Relay within the larger community (ClojureScript, TypeScript, etc.), and, if someone does refactor this to support a portable compiler function, I will commit to packaging it for use by the ClojureScript community. |
:edit: oops I am dumb @chandu0101 posted this approach as the first comment ;p I messed with this a month or so ago (just saw this issue). The thing I was doing, and no idea if it was a good idea or not, was shelling to node.js from clojure. So you might have something like: (relay "query { viewer { name } }") This would call the babel transformer directly with the Relay plugin configured, get the AST, and then execute it (it turns an AST of a function call so you have to eval it), and return a JSON string of the AST. This json string could then be parsed by clojure. I am clojurescript dumb so I wasn't sure the best way to do this so it happens in clojure vs clojurescript. I think a macro would happen in clojure and clojurescript could be left with just a js object? ;; this in code ...
(def a-query (relay "query { viewer { name } }"))
;; ... produces this in clojurescript?
(def a-query #js { ... AST ... }) I also tried a reader literal: (def a-query #relay/ql "query { viewer { name } }") The downside to this whole approach was that I was shelling to node.js per query ... so that is slow. Ideally nashorn could do this but I read it can't load babel so didn't even try. I'm sure you could do it so that it fires node.js once and then just streams queries in / out ... but I am not that smart :). Knowing that the babel stuff is passed as parameters to the Printer sounds rad. I'd like to give that a try so I wouldn't need babel and could do this all in nashorn. |
Here was the script: var babel = require('babel-core');
var language = require('graphql/language');
var utilities = require ('graphql/utilities');
var getBabelRelayPlugin = require('babel-relay-plugin');
var graphql = require('graphql');
const ast = language.parse('type Viewer { id: ID! name: String } type Root { viewer: Viewer }');
const schema = utilities.buildASTSchema(ast, 'Root');
graphql.graphql(schema, utilities.introspectionQuery).then(function(data) {
var plugin = getBabelRelayPlugin(data.data);
try {
var query = process.argv[2];
console.log(JSON.stringify(eval(babel.transform('Relay.QL`' + query + '`', {plugins: [plugin]}).code)));
} catch (e) {
console.log(JSON.stringify({error: e.message}));
}
}); So ... extremely low tech ;p It would be rad if that could just run in nashorn but babel stops it? |
@eyston That's very similar to what I am currently doing. (ns project.relay
(:require
[clojure.java.io :as io]
[me.raynes.conch :as conch]))
(defn ^:private ql* [env query]
(let [rql (str "Relay.QL`" query "`")
schema (-> "relay/schema.json" io/resource slurp)
filename (-> env :ns :name)
script (str "var schema = " schema ";"
"var schemaData = schema.data;"
"var getBabelRelayPlugin = require('babel-relay-plugin');"
"var babel = require('babel-core');"
"var plugins = [getBabelRelayPlugin(schemaData)];"
"var filename = '" filename "';"
"var options = {plugins, filename, comments: false, ast: false};"
"var code = '" rql "';"
"babel.transform(code, options).code;")]
(conch/execute "node" "--print" script)))
(defmacro ql [^String query]
(list 'js* (ql* &env query))) I opened #962 specifically because I'd like to switch from shelling out to Node to directly compiling in Nashorn. The only thing stopping us JVM users (CC @chandu0101) from using Relay with Nashorn is that |
awesome, thanks! I like that you can just inline the code directly versus having to eval. :) |
(Spring-cleaning). Going to close this one due to inactivity. Summarizing the thread: a couple of workarounds have been shared, and we're open to PRs. Note also that Relay has a new core now (pieces of which have been landing on the master branch for some time now, with more to come), so if we want to continue discussion of this further we should probably do so in a new issue, and based the discussion on the current reality (and imminent future) of the master branch. In them meantime, thanks for the discussion on this issue! |
If anyone lands here looking for a relay plugin for Typescript, I just published a package that converts between the output generated by https://github.com/pathgather/typescript-relay-plugin |
I described the setup in this issue at babel-plugin-macros. |
@jsphstls If you (or anyone else) happen upon this thread, I created a fresh one at #3319 I ask about "next generation" JS bundlers and generally where relay fits between compilers. At the moment - I'm a little fuzzy on what relay ingests, outputs, and if it's possible for us to make it work simply with plain-old The reason why is, like many, build setups have been a copy-paste thing for me. What node, webpack, babel, tsc, and relay do are blurred. I've been focused on building out product for users, and not looking at what's under the hood. I can't tell how they depend on one another. It's a blur to me. Am I the only one? I imagine it should be getting smoother and smoother! My understanding is node and webpack can hande more recent ES (as well as browsers in general), but still, TypeScript and relay are their own kind of thing. |
For anyone using Vite and looking to get relay-compiler running without babel, I use the following setup:
And that seemed to work for me. |
It looks like Relay currently requires Babel to compile
Relay.QL
strings. This is unfortunate because it makes Relay unusable from compile-to-JS languages like ClojureScript (where React is the dominant rendering library) and TypeScript.I searched for issues about decoupling Relay from Babel but didn't find any. What is the status of this? Is Relay going to be permanently tied to Babel or is this temporary? It would be great if there were a self-contained Relay package that could run entirely client-side. Perhaps this may not be possible or be too slow to be feasible, in which case the compilation logic could be packaged separately and thereby made accessible to build tools other than Babel.
The text was updated successfully, but these errors were encountered: