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

Fragments #25

Closed
pasiba opened this issue Dec 4, 2016 · 3 comments
Closed

Fragments #25

pasiba opened this issue Dec 4, 2016 · 3 comments

Comments

@pasiba
Copy link

pasiba commented Dec 4, 2016

Can I use fragments with loader?

@stubailo
Copy link
Contributor

stubailo commented Dec 6, 2016

Not right now, I had some ideas here: apollographql/apollo-client#994 (comment)

@jtmthf
Copy link

jtmthf commented Dec 29, 2016

I've been hacking around on this and have a half-baked solution using the loader and @stubailo's idea of using a directive.

What works well is first declaring the directive in your schema. I've been using this declaration so far,

# Import a fragment from an external file
directive @import(
    # Path to import fragment from
    from: String!
  ) on FRAGMENT_SPREAD

As far as I can tell, graphql-js only provides a way to define custom directives, but not their runtime. This is fine though as @import would have no runtime implications. So far testing this on graphiql works great, and I assume it would on any other tool that reads a schema such as apollo-codegen and eslint-plugin-graphql.

Right now I have the loader set to parse the query using gql as it always has, but then visit the AST using something like this,

visit(ast, {
  Directive: {
    enter(node) {
      if (node.name.value === 'import') {
        const fromArg = node.arguments.filter(arg => arg.name.value === 'from')
        addImport(fromArg.value.value)
      }
      return node;
    }
  }
});

One thing to note is that the loader currently doesn't strip @import from the query. It doesn't really hurt or help to do so, although I'd appreciate some feedback on which approach is best.

Lastly, a require() is inserted for each import which brings the final emit to look something like,

`var fragments = ${imports.map(path => `require(${path})`)}
  
var query ${JSON.stringify(gql`${source}`)};

query.documents = query.documents.concat(fragments)

module.exports = query`

Overall not too complicated of a loader. Biggest concern of mine is if custom directives are considered taboo still, or if they are safe to implement.

@pasiba
Copy link
Author

pasiba commented Jan 11, 2017

Good.

@pasiba pasiba closed this as completed Jan 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants