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

Proposal: importing .graphql files should be enabled #1792

Closed
kjetilge opened this issue Mar 11, 2017 · 20 comments
Closed

Proposal: importing .graphql files should be enabled #1792

kjetilge opened this issue Mar 11, 2017 · 20 comments

Comments

@kjetilge
Copy link

Right now I need to eject in order to import .graphql files (using graphql-tag/loader) . I would think graphQl is some kind of core technology that should be supported out of the box ?

@pselden
Copy link

pselden commented May 19, 2017

Ejected for this same reason.

@gaearon
Copy link
Contributor

gaearon commented May 19, 2017

I’m open to supporting this, but is it Apollo-specific? Would it work for people using Relay Modern too?

@pselden
Copy link

pselden commented May 19, 2017

I dont think it's apollo specific -- but I have not verified yet.

From this:

query ChannelsList {
  channels {
    id
    name
  }
}

You end up with this:

{
  "kind": "Document",
  "definitions": [
    {
      "kind": "OperationDefinition",
      "operation": "query",
      "name": {
        "kind": "Name",
        "value": "ChannelsList"
      },
      "variableDefinitions": [],
      "directives": [],
      "selectionSet": {
        "kind": "SelectionSet",
        "selections": [
          {
            "kind": "Field",
            "alias": null,
            "name": {
              "kind": "Name",
              "value": "channels"
            },
            "arguments": [],
            "directives": [],
            "selectionSet": {
              "kind": "SelectionSet",
              "selections": [
                {
                  "kind": "Field",
                  "alias": null,
                  "name": {
                    "kind": "Name",
                    "value": "id"
                  },
                  "arguments": [],
                  "directives": [],
                  "selectionSet": null
                },
                {
                  "kind": "Field",
                  "alias": null,
                  "name": {
                    "kind": "Name",
                    "value": "name"
                  },
                  "arguments": [],
                  "directives": [],
                  "selectionSet": null
                }
              ]
            }
          }
        ]
      }
    }
  ],
  "loc": {
    "start": 0,
    "end": 55,
    "source": {
      "body": "query ChannelsList {\n  channels {\n    id\n    name\n  }\n}",
      "name": "GraphQL"
    }
  }
}

@pselden
Copy link

pselden commented May 19, 2017

Looks like Relay.QL is vastly different. It uses a precompiled schema and validates your graphql against it. Whereas graphql-tag/loader just spits out the document and handles imports (that also might be a graphql-tag/loader specific concept).

@notrab
Copy link

notrab commented May 24, 2017

Yep, I'm having to eject too on a brand new project just to support this.

Really good if there were a way to bake this in, or even better add custom loaders somehow 🙌

@koistya
Copy link
Contributor

koistya commented May 31, 2017

As of Relay Modern, there must be "babel-plugin-relay" baked into the Babel config.

@notrab
Copy link

notrab commented Aug 1, 2017

Has anyone had any further thoughts on how we best implement this?

Graphcool today announced graphql-cli and it would be awesome to submit a PR over there that CRA works out of the box with graphql-cli.

@gaearon
Copy link
Contributor

gaearon commented Jan 8, 2018

Note this issue won't progress by itself. If you're interested in this please create a proof of concept, send a PR, help us understand whether it's Apollo-specific or not, etc. Thanks!

@iamclaytonray
Copy link
Contributor

@gaearon - From what I have tested so far, it is Apollo-specific. Would a good alternative be to add both graphql-tag/loader and babel-plugin-relay to CRA to handle both use-cases?

@iamclaytonray
Copy link
Contributor

iamclaytonray commented Jan 16, 2018

If the above isn't a good alternative, I only see two other options:

  1. Don't support it. Let users continue to eject from CRA to add this manually.

  2. Someone (possibly myself) can write a Webpack Plugin to handle both Relay and Apollo. I have no idea what the implementation would look like or even if the two would play nicely together. I wish I had a better answer but I'd have to play around with it before giving anything concrete. Sorry 😞

(Or just support one. I don't see that as an ideal solution, though.)

@gaearon
Copy link
Contributor

gaearon commented Jan 16, 2018

For Relay, I’d like to see if recently merged babel-plugin-macros support is enough.

For Apollo, it seems to me odd to hardcode a filetype loader to a specific library 😞 But maybe if apollo is in package.json we could do it automatically. The trick is how to make sure every ejected user doesn’t have to deal with config for this if they don’t use this.

@iamclaytonray
Copy link
Contributor

I haven't seen babel-plugin-macros yet so I'll have to research it/dig through the source.

Ideally, we should have a global GraphQL plugin/loader that handles Apollo, Relay, and any other GraphQL lib/framework.

I'm not sure about a good solution to the last statement you made. For users who are not using GraphQL, it adds a bit more bloat to the node_modules but past that, it shouldn't affect the rest of the app. I'm not sure though

@iamclaytonray
Copy link
Contributor

I'll note that if we come up with a good solution, I'm more than happy to submit a PR to close this issue.

@kentcdodds
Copy link
Contributor

kentcdodds commented Jan 16, 2018

Someone could probably build a macro to support reading in .graphql files:

// some-file.js
import graphqlLoader from './graphql-loader.macro'

const query = graphqlLoader('./query.graphql')




// graphql-loader.macro.js
const {createMacro} = require('babel-plugin-macros')

module.exports = createMacro(graphqlLoaderMacro)

function graphqlLoaderMacro({references, state, babel}) {
  const {file: {opts: {filename}}} = state
  references.default.forEach(graphqlLoader => {
    const relativeQueryPath = graphqlLoader.parentPath.get('arguments')[0].node.value
    const queryPath = path.relative(filename, relativeQueryPath)
    // do the queryPath loading thing
    // replace graphqlLoader.parentPath with whatever you loaded...
  })
}

The cool thing is you could do this locally in your own project before it's even published to npm. All without having to configure anything at all. Then when someone's got a good working version they can publish it to npm and anyone can use it. It's 100% explicit what's going on and it works without any configuration necessary! 🎉

@gaearon
Copy link
Contributor

gaearon commented Jan 16, 2018

Smart. Since we landed babel-plugin-macros support let's just close this, and then somebody can build a macro for it.

@gaearon gaearon closed this as completed Jan 16, 2018
@ibigpapa
Copy link

@kentcdodds I'd like to see the setup for this and how to use in practice as an example if possible.

@kentcdodds
Copy link
Contributor

@ibigpapa,

I don't know if I have time. I also don't know much about graphql, so I may not be the right one to make this. But it does seem interesting to me, so if I have time I'll work on it.

Honestly I don't think it's much more than my example above. You'll probably need fs.readFileSync to read the file to a string, then do whatever processing you need to convert it to the format needed, then convert that to an object AST and call graphqlLoader.parentPath.replaceWith(yourQueryObjectAST). I wouldn't say it's "easy," but it shouldn't be too much more than what I provided above.

For folks wanting to learn more about this, see the babel-plugin-macros author docs which has links to resources about working with ASTs in babel.

@evenchange4
Copy link
Contributor

evenchange4 commented Jan 19, 2018

@kentcdodds Thank for your suggestion. I try to implement it with babel-plugin-macros. It ls really
cool. 😀 Now, we can import .graphql files without webpack configuration:

$ yarn add graphql.macro
import { loader } from 'graphql.macro';
const query = loader('./fixtures/query.graphql');

           

const query = {
  "kind": "Document",
  "definitions": [{
    ...
References

GitHub: https://github.com/evenchange4/graphql.macro
Example: https://github.com/evenchange4/graphql.macro-example
Demo: https://graphqlmacro.netlify.com/

@kentcdodds
Copy link
Contributor

This is super @evenchange4! Would you like to add your macro to the list? And make sure to add the keyword babel-plugin-macros to your package.json so it's easier to find on npm!

Well done @evenchange4! 👏

@gaearon
Copy link
Contributor

gaearon commented Feb 3, 2018

Importing .graphql files will work out of the box with no extra manipulation in 2.x: #3909

@lock lock bot locked and limited conversation to collaborators Jan 20, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants