Repository navigation
Multi-project graphql-config for the LSP: schema, documents, include, exclude, and fast startup #4616
Unanswered
unrevised6419
asked this question in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
I spent some time getting the GraphQL language server (vscode-graphql 0.13.x / graphql-language-service-server 2.15.0, graphql-config 5.1.6) to behave in a pnpm monorepo with three schemas. Sharing what I learned, because the interplay between
schema,documents,includeandexcludeis not obvious, and one setting turned a ~15 s startup into an almost instant one.The setup
Three projects, each with its own schema and its own document suffix (
*.api.gql,*.cms.gql,*.crm.gql). GraphQL also appears in.tsfiles that the LSP should ignore (they are handled by other tooling).What each key actually does
graphql-config decides which project a file belongs to with
GraphQLProjectConfig.match():and
GraphQLConfig.getProjectForFile()falls back to the first project that has neitherincludenorexcludewhen nothing matches.documents: the files the LSP pre-loads at startup. Fragment definitions are only indexed from here, so without it you getUnknown fragment "X"for fragments defined in other files.schema: also counts as "belongs to this project".include/exclude: only affect project membership; they never load anything.excludeis additionally used as the globignorelist when loadingdocuments.includeorexcludeon a project removes it from the fallback. That is the switch that stops the LSP from validating.tsfiles that are not part ofdocuments(see [lsp-server] 🐞 JS/TS files should only be checked when included indocumentsconfig glob #3588).The config that works
Notes:
schemamust be relative to the config file. An absolute path loads the schema fine, but never matches inmatch(), so the schema files end up in no project (File '.../api.schema.graphql' doesn't match any projectin the output). Withoutinclude/excludethe fallback hides this, and assigns all schema files to the first project.documentsandincludeboth.includealone breaks fragment lookup;documentsalone keeps the fallback and validates every.tsfile.there was an error loading the project config for this file ... doesn't match any project. It is harmless; the file is simply skipped (LSP Server: No Errors on mismatched file #2498).Startup speed: exclude
node_modulesThe LSP loads
documentsthrough graphql-tools, which does not ignorenode_modulesby default. A root-level glob like**/*.api.gqltherefore walks the whole pnpm store, once per project. Measured in our repo (warm FS cache, same 32/13/7 files found in every case):exclude**/node_modules/****/dist/**,**/generated/**,**/coverage/**Cold, the unexcluded case took ~15 s before
GraphQL Language Server caches initializedshowed up, and go-to-definition did nothing until then. With the exclude list startup is effectively instant.Dot-directories (
.next,.nx,.git) are already skipped, since the glob does not match dot paths by default. So the useful additions are build outputs (dist,build,coverage, generated code) that live in regular directories.Do not put the excludes in
documentsas!**/node_modules/**: negated globs indocumentsmakematch()returntruefor every file outsidenode_modules, which brings back the.tsvalidation. Useexclude.Related issues
documentsconfig glob #3588:.tsfiles validated through the fallback projectmatch()didClosehandler not boundnode_modules_cacheSchemaFiledrops the projectAll reactions