Reload schema in eslint-server if file with schema was changed
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.
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 :)
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
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
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) 😏
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 :)
Alrighty... So, this is a little heavy-handed, but it should be a viable workaround for most cases:
tl;dr
- Use the Run It On extension to watch for file changes and execute a command.
- 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.
- Execute that command using Run It On.
More detail:
-
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)
-
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"]
},
]
- Set up the Run It On config in
settings.jsonalong these lines. Adjust to accommodate your use-case. I use thewatcherssetting because my schema is codegen'd. You can also use thecommandssetting if you just want basic "run on save" behavior. Just note, thecommandssetting 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 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
@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 😅
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
released in @graphql-eslint/[email protected]
@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
It has a 10secs delay to omit reloading schema/documents on every file change
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 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
@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?