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

Reload schema in eslint-server if file with schema was changed

Open nodkz opened this issue 4 years ago • 8 comments

Is your feature request related to a problem? Please describe.

We open monorepo in VSCode where installed eslint with graphql-eslint plugin. And open some graphql file in client folder with query operation and decide to refactor server schema. We change code in the server folder and after that, some watcher replaces schema.graphql file with new type definitions. But eslint-server still checks graphql operation in the client folder with old schema (loaded on vscode start up).

Describe the solution you'd like

It will be nice if Eslint-server in VSCode automatically reloads graphql schema and does not use stale information for validation rules.

Describe alternatives you've considered

Run manually "Restart ESLint Server" command when schema.graphql file was changed.

Additional context

Especially it works funny when we use some graphql plugin for vscode and graphql-eslint simultaneously. After schema changes developer gets a validation error from vscode plugin for old field name, and from graphql-eslint for the new value name123. Most developers will be confused and think that both field names are incorrect.

Screen Shot 2021-08-23 at 23 15 11 Screen Shot 2021-08-23 at 23 14 58

nodkz avatar Aug 23 '21 18:08 nodkz

Hi @nodkz ! Thanks for reporting it! I think the actual issue is coming from VSCode, since there is no way to connect ESLint server and a specific file / watch :/

Keeping open until we'll figure this out :)

dotansimha avatar Sep 06 '21 09:09 dotansimha

I also I think there is a similar problem with the "no-unused-fields" rule. When I alter an operation to use a previously unused field by adding that exact field to my operation, vscode eslint extension still reports the error in the schema file as unused. So I have to restart the eslint server to make it able to see the changes I made

Axedyson avatar Nov 01 '21 21:11 Axedyson

I've compiled the following little list of rules that suffers the same issue that I stated in my comment above:

"@graphql-eslint/no-unused-fields"
"@graphql-eslint/no-unreachable-types"
"@graphql-eslint/fields-on-correct-type"
"@graphql-eslint/known-type-names"
"@graphql-eslint/unique-operation-name"
"@graphql-eslint/unique-fragment-name"
"@graphql-eslint/require-id-when-available"
"@graphql-eslint/provided-required-arguments"
"@graphql-eslint/known-argument-names"

Note that there might be more rules that suffer from the same issue

Axedyson avatar Nov 29 '21 22:11 Axedyson

There's now a command to restart the eslint server (https://github.com/microsoft/vscode-eslint/issues/477#issuecomment-808597443) ... would it make sense for this extension to have a watcher on the files containing the schema and restarting the eslint server if any of those changes?

If you (as the maintainers) disagree, and argue that this would be better to manage in the vscode-eslint repo, can you please open a ticket there, so we can move this a step forward?

It would at least be good to add a note for this on the readme, I think, specially because there already is a section about vscode (https://github.com/dotansimha/graphql-eslint#vscode-integration) 😏

SimonSimCity avatar Feb 08 '22 08:02 SimonSimCity

I just wanted to add that in #985 I describe that this also affects linting of the schema in the backend, not just the operations in the frontend. The issue is not specific to monorepos or frontend operations :)

joshribakoff-sm avatar Mar 08 '22 17:03 joshribakoff-sm

Alrighty... So, this is a little heavy-handed, but it should be a viable workaround for most cases:

tl;dr

  1. Use the Run It On extension to watch for file changes and execute a command.
  2. Use the multi-command extension to create a joint command that restarts both the eslint server and the vscode-graphql server. This might not be necessary, but in my case, just running one or the other doesn't seem to work.
  3. Execute that command using Run It On.

More detail:

  1. Install Run It On v2 (I forked the original version and republished as a new extension -- the old version is broken and unmaintained; I didn't fix everything with the extension, but just enough to use for these purposes... I don't have plans to regularly maintain this, but I may update as necessary if it breaks for me)

  2. Install the multi-command extension and set up a muilti-command like this in your settings.json:

"multiCommand.commands": [
    {
      "command": "multiCommand.restartGraphQLLinting",
      "sequence": ["eslint.restart", "vscode-graphql.restart"]
    },
  ]
  1. Set up the Run It On config in settings.json along these lines. Adjust to accommodate your use-case. I use the watchers setting because my schema is codegen'd. You can also use the commands setting if you just want basic "run on save" behavior. Just note, the commands setting uses regex instead of glob, so you'll need to adjust for that.
"runItOn": {
   "watchers": [
     {
       "match": "**/*.{gql,graphql}",
       "isShellCommand": false,
       "cmd": "multiCommand.restartGraphQLLinting"
     }
   ]
 }

Disclaimer

As I mentioned, this is probably heavy-handed. I'm sure there's a much better way to do this through the extension host, but I don't have the time or patience right now to learn much more about vscode extensions than I had to for this.

Hope this helps some folks out there while the vscode or graphql teams get around to addressing this more elegantly.

jonnyasmar avatar Sep 16 '22 07:09 jonnyasmar

@jonnyasmar any reason to do it this way over moving the logic that reads the GQL schema out of the extension host (which I'm assuming only runs once when the process starts), and running it instead directly inside the lint rule (which is run each time code is changed). Some advantages would be that it could still lint in memory changes in unsaved files, and does not require restarting the extension host Edit - Ah I see you're specifically using a workaround, and not a maintainer of the repo

joshribakoff-sm avatar Sep 16 '22 16:09 joshribakoff-sm

@jonnyasmar any reason to do it this way over moving the logic that reads the GQL schema out of the extension host (which I'm assuming only runs once when the process starts), and running it instead directly inside the lint rule (which is run each time code is changed). Some advantages would be that it could still lint in memory changes in unsaved files, and does not require restarting the extension host Edit - Ah I see you're specifically using a workaround, and not a maintainer of the repo

Yeh, it would be ideal to not have to restart the linters, but that's a bit over my head. Definitely just a hacky workaround here 😅

jonnyasmar avatar Sep 16 '22 16:09 jonnyasmar

Hi @nodkz @jonnyasmar @joshribakoff-sm @SimonSimCity @Axedyson, @matthew-valenti, @acidoxee and @jonnyasmar ! Future release with cache invalidation could be tested in the following alpha version 3.13.0-alpha-20221024000319-1089aa0

dimaMachina avatar Oct 30 '22 00:10 dimaMachina

@B2o5T It does not seem to behave any differently after upgrading (yarn add @graphql-eslint/[email protected]), after editing my schema to comment and uncomment a field, the lint error in a separate query file does not go away / come back until I reload the VScode window.

I have a .graphqlconfig at the top of my repo:

schema: libs/backend/gql-modules-*/src/*/*.graphql
documents: libs/frontend/api-client/src/**/*.gql

joshribakoff-sm avatar Nov 01 '22 15:11 joshribakoff-sm

It has a 10secs delay to omit reloading schema/documents on every file change

dimaMachina avatar Nov 01 '22 15:11 dimaMachina

Looks like closing the document in my editor, and opening that file again works. I guess it's a limitation of vscode itself that it doesn't know to re-run linting on the document when the schema has changed. Another workaround seems to be to make any edit to the document and then undo the change, which also forces the linter to run.

joshribakoff-sm avatar Nov 01 '22 16:11 joshribakoff-sm

@joshribakoff-sm if you have any idea how this can be improved feel free to share :) for the invalidation cache I was inspired by eslint-plugin-import solution

dimaMachina avatar Nov 01 '22 17:11 dimaMachina

@joshribakoff-sm if you have any idea how this can be improved feel free to share :) for the invalidation cache I was inspired by eslint-plugin-import solution

can I ask what's the mechanism to reload on file change? Does it mean we push the file to a cache and invalidate cache every some seconds?

cuongn265 avatar Aug 23 '23 07:08 cuongn265