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

Import fragments from a exernal file #43

Closed
alonp99 opened this issue Nov 29, 2016 · 13 comments
Closed

Import fragments from a exernal file #43

alonp99 opened this issue Nov 29, 2016 · 13 comments

Comments

@alonp99
Copy link

alonp99 commented Nov 29, 2016

Hi,
Great plugin, I really enjoy it!
I wonder if it is possible to enable an import of fragments that then can be used in .graphql query files and run against a server endpoint.

The motivation is to reuse fragments in static queries.
maybe add a fragments folder in graphql.config?

@jimkyndemeyer
Copy link
Collaborator

Hi alon.

Thanks for using the plugin.

If I'm not mistaken, I think you can achieve something like imported fragments using template strings:

const fragmentOnUser = require('./fragmentOnUser.graphql');
const query = `{ user { ${fragmentOnUser} } }`;

See https://github.com/kadirahq/lokka#using-fragments for inspiration.

@alonp99
Copy link
Author

alonp99 commented Nov 29, 2016

Thanks for the quick response. I do kind of the same thing, but I cant get the benfits of the plugin like that.
I will try to explain the use case a bit better.

lets say I have "resuable-fragment1.graphql", "resuable-fragment2.graphql" and "some-query-file.graphql" that look like that

{
     root {
        field1
        field2
     }
     ...reusable-fragment1
}

now at runtime I concat "reusable-fragment1.graphql" to "some-query-file.graphql" and the query resolves fine.

but when I inspect "some-query-file.graphql" using the plugin I see error on "...resuable-fragment1", also i cant run the query directly from the plugin because there no way to import resuable fragments in graphql.config.
I think that will be a good feature, does it make sense?

@jimkyndemeyer
Copy link
Collaborator

Ah, I see.

I don't have a lot of free time to work on the plugin at the moment, and I think this might take a while to implement. But I'll consider this for a future release.

/Jim

@alonp99
Copy link
Author

alonp99 commented Dec 1, 2016

Fair enough, Thanks Jim.

@armstrjare
Copy link

+1 on this.

I'm using .graphql files to define all my queries and mutations. I like to keep the reusable Fragment definitions side-by-side with the relevant component/template that they relate to, so these will be in separate files.

I use https://github.com/apollostack/graphql-document-collector to parse all my GraphQL into a single document file for including in my app. This automatically handles including the right fragments etc.

It would be great if the plugin could automatically assume that global fragment files will be available for use in GraphQL queries. Presently, a warning is shown that the Fragment is not defined.

@smitt04
Copy link

smitt04 commented Mar 21, 2017

+1 for this feature. I actually use import comments to tell my interpreter where the fragments are. Something like

#import "fragments/path/to/fragment.graphql"

This makes it valid graphql, since it is just a comment, yet my parser can easily read it out and cat the file into its place.

@mjpvandenberg
Copy link

@smitt04 This doesn't seem to work for me in PhpStorm 2017.3.2. Where exactly in the .graphql file should I use that line? Are you aware of any limitations to this approach/workaround?

Also, does your IDE still give you Fragment "YourFragmentName" is never used. errors when viewing the fragment file?

@smitt04
Copy link

smitt04 commented Jan 4, 2018

@mjpvandenberg I just put that line at the top of the file. It is not supported in this plugin, it just is a comment. Still get the Fragment is never used. I current am using a custom parser that reads those import statements and injects the fragments. Here is a link to the gql-loader webpack plugin that i made.

@fenok
Copy link

fenok commented Feb 1, 2018

Any progress on this?

@jimkyndemeyer
Copy link
Collaborator

Hi @fenok

No progress. A PR would be very welcome.

Best regards,
Jim.

@axnsan12
Copy link

Hello,

Just weighing it with more examples, this is also used by the apollo graphql-tag webpack loader: https://www.apollographql.com/docs/react/recipes/webpack.html#Fragments. So I would say it is a pretty common and prevalent syntax which would be worth supporting.

It can also take the form of #import "graphql-tag/loader!./FileWithFragment.graphql" (i.e. with an explicit loader specified before an ! sign, cf. webpack require syntax).

Functionally it is equivalent to a textual substitution of the referenced file, which is usually expected to contain a single fragment.

I'd say desired features would be:

  • go to definition on the import statement (to open the referenced file)
  • autocomplete with the fragments imported from the file after ...
  • go to definition on usages of the fragment itself
  • find usages from the fragment .graphql file
  • ability to run queries which use #imported fragments

What could be problematic is accurately resolving the imported file according to webpack rules, it would be really useful if the actual webpack import logic could be used somehow.

I would be open to spending some time on this, but it seems non-trivial and I have no experience with jetbrains extensions 😕. I got pretty confused after looking a bit through the code, so maybe some pointers on how this could be implemented would help to move it forward?

@jimkyndemeyer
Copy link
Collaborator

@axnsan12 Thank you for weighing in.

I see two main threads in your comment:

  1. How can people contribute to this plugin?
  2. How exactly should the import feature work?

I'll address each below.

Contributing

I'd like to have more contributors to help out with the plugin, but language tooling has a somewhat steep learning curve as you found out.

To contribute non-trivial features to this plugin, I would say that you need experience with the IntelliJ Platform SDK, specifically custom language support. If you are willing to spend the time necessary, the documentation at https://www.jetbrains.org/intellij/sdk/docs/welcome.html is the best starting point.

Once you understand the architecture and core concepts, the custom language tutorial at https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support_tutorial.html is the most relevant for this plugin.

If you're up for it, I'd be happy to have more people helping out with the plugin.

Imports

I thought some more about this. The most central discussion I could find is graphql/graphql-spec#343

Given the complexity of import path resolution logic and the cross-cutting nature of the feature, I prefer to see a consensus form before introducing import support in the plugin. Here's why:

As I see it, people are still very much experimenting with their GraphQL project structures and build setups. Attempting to keep up in this plugin seems unfeasible, given that the plugin not only has to understand the underlying rules of each setup, but also implement language tooling on top of it.

As to the features you mention, some of them are partly there now that Relay Modern support was added. You will see completion to all known fragment names after ..., and you can navigate/find usages based on the Relay Modern logic that all queries and fragment names are considered unique within a project. The complication here is that for other project types, this might not make sense or even be in direct conflict.

I think the way forward here is to help establish a consensus that can inform exactly how the feature should work.

jimkyndemeyer added a commit that referenced this issue Apr 14, 2019
…243, #43, #94)

- Highlight current executable operation and included fragments
- Automatically include referenced fragments, including across files based on resolving PSI references
@jimkyndemeyer
Copy link
Collaborator

The RFC to add imports to GraphQL was closed without arriving at a standardized solution.

The 2.0 release of this plugin shipped with a capability to resolve fragments across files, but bounded by schema scopes defined using graphql-config. The scoping allows for control over which fragments are visible from specific operations. Completion and error highlighting for fragment spreads follows this scoped resolution logic.

For the upcoming 2.1 release contextual queries will automatically include these "resolvable" fragments when executing operations against GraphQL endpoints.

This approach allows developers to use whatever import mechanism they deem as most fitting while adding a better DX while working with this plugin. The developers must take care to test their components actually import the required fragments, but testing is an established best practice.

With the 2.0 release the plugin achieved compliance with the June 2018 GraphQL spec. Should imports become a part of an upcoming spec version I'll revisit as needed.

Best regards,
Jim.

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

No branches or pull requests

7 participants