graphql-tools icon indicating copy to clipboard operation
graphql-tools copied to clipboard

the `import` expression only works if one appears at start of file (seo: graphql-tools import expression not working)

Open keilin-anz opened this issue 8 months ago • 2 comments
trafficstars

Overview

The import expression must be the first non-blank line of a file, otherwise no imports are processed.

Not a big deal, but as a first-time user it left me scratching my head for a fair while before discovering the reason - just hoping to save future peoples' scalps 😁

[!NOTE] I've made this issue overly detailed since I can't raise a PR from where I am, but also it's unclear what the preferred fix would be (perhaps this should have been a discussion instead?)

Context

  • processImport condition depends on isGraphQLImportFile
    • https://github.com/ardatan/graphql-tools/blob/5ebc523d524f8c657e6f92dc1619b076a74c05c5/packages/loaders/graphql-file/src/index.ts#L212-L213
  • isGraphQLImportFile only checks first non-blank line
    • https://github.com/ardatan/graphql-tools/blob/5ebc523d524f8c657e6f92dc1619b076a74c05c5/packages/loaders/graphql-file/src/index.ts#L39-L41

Concern

The above behaviour isn't documented (AFAICT)

link to (presumedly) relevant section: https://github.com/ardatan/graphql-tools/blob/5ebc523d524f8c657e6f92dc1619b076a74c05c5/website/src/content/schema-loading.mdx?plain=1#L91-L94

[!NOTE] Whilst this could be as simple as adding a callout to the documentation, there may be other options..

Examples

quietly fails:

# This schema has some heading context, or a license, etc..
# and then has an import
#import * from 'this-will-fail-silently.graphql'

works fine:

#import * from 'this-will-work-fine.graphql'
# This schema has some heading context, or a license, etc.. after its import

interestingly enough, this also works fine (since invalid import lines are ignored):

#import
# This schema has an invalid import at the top which (unintended benefit!) acts as a pragma
# to enable the following to still work
#import * from 'this-will-work-too.graphql`

## Suggestions

### Option 1

If this is desired behaviour, then perhaps just adding a callout:

````diff
### Using `#import` Expression

+<Callout type="warning">
+  at least one `#import` directive must be the first non-blank in a file
+</Callout>
+
Assume the following directory structure:

```text

Option 2

Since the extractImportLines function will happily extract import expressions from anywhere in the file, you could conceivably loosen the restriction defined in isGraphQLImportFile and simply let it check whether a file has import expressions on any line

[!NOTE] This does require searching a (potentially) much longer string

If performance is a concern, you could always retain the current first-line logic as an early-out check. (and potentially include a note in the documentation along the lines of "if you are working with very large graphql files and performance is a concern you can regain some speed by ensuring at least one of your import expressions is at the top of the file")

Option 3

Add validation for import lines - this doesn't actually solve the key issue (the validation would still only run if an import line appears at the top) but perhaps if combined with Option 2 this would reduce some headaches

Option 4

Do neither of the above and just trust that people will find this issue 😁

keilin-anz avatar Mar 04 '25 10:03 keilin-anz