-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
feat: support vscode multi-root workspaces #2594
Conversation
🦋 Changeset detectedLatest commit: ad87012 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Wow ok, i hadn’t thought of starting multiple instances. I was just going to re-architect the server to handle each workspace in the same server. Does this work when multiple graphql config projects are defined in a file? either way, awesome work and thank you for this! |
Codecov Report
@@ Coverage Diff @@
## main #2594 +/- ##
==========================================
+ Coverage 65.70% 69.61% +3.90%
==========================================
Files 85 72 -13
Lines 5106 4275 -831
Branches 1631 1436 -195
==========================================
- Hits 3355 2976 -379
+ Misses 1747 1294 -453
- Partials 4 5 +1
Continue to review full report at Codecov.
|
Sorry, I have not checked on multiple projects. |
@Foo-x hey that would be great, if I don’t get to it first! No hurry at all, but don’t be surprised if this gets released before you wake up! thank you so much for this! |
@Foo-x i think this is good to go, can you add a changeset file with your changelog entry as well? it seems there are unrelated issues with |
add a changeset for the changelog, so that the version increments
@acao Thank you for adding the changeset! Regarding the behavior in multi-projects, I found a problem that intellisense is displayed twice.
{
"projects": {
"alpha": {
"schema": ["alpha/**", "shared/**"]
},
"beta": {
"schema": ["beta/**", "shared/**"]
}
}
} # shared.graphql
type Shared {
shared: Boolean
}
# alpha.graphql
type Query {
sharedAlpha: Shared
}
# beta.graphql
type Query {
sharedBeta: Shared
betaAnother: BetaType
}
type BetaType {
foo: Boolean
} on on Let me see if I can fix it. |
But there is yet another problem that if there is a GraphQL config file outside the nested folders, the inner folders always belong to the outside folder as a project.
{
"projects": {
"alpha": {
"schema": ["alpha/**", "shared/**"]
},
"beta": {
"schema": ["beta/**", "shared/**"]
}
}
} on If you don't add I think the server needs to be implemented to solve this problem. |
Yes @Foo-x this is one of the longstanding known bugs in the LSP server I was referring to. You are free to try and fix it in the server in this PR, or we can fix it later. What you’ve implemented works great! |
Ok, I'll try it! |
@Foo-x this is amazing work! Would you like to pair? I have a few more relatively simple optimisations we can add. Are you on the discord? https://discord.com/channels/625400653321076807/863688312756371476 my mission this weekend is to get this and some other features and optimisations out to celebrate a million installs for |
I would also love to explain some problematic architecture and hacks of mine that you're inevitably stumbling into 😆 , and how I envision this server could be architected better. For example: I put way too much logic in As you probably know this is the LSP client file-watcher pattern that we never fully moved to from the pre-LSP days of this language server. I adopted it after it had transitioned to LSP model, but at the time |
@Foo-x also, another huge and relatively low-hanging optimization that leads to deleting a bunch of code is rewriting This beast i see you've commented out: /**
* This should only be run on initialize() really.
* Caching all the document files upfront could be expensive.
* @param config {GraphQLConfig}
*/
async _cacheAllProjectFiles(config: GraphQLConfig) {
if (config?.projects) {
return Promise.all(
Object.keys(config.projects).map(async projectName => {
const project = config.getProject(projectName);
await this._cacheSchemaFilesForProject(project);
await this._cacheDocumentFilesforProject(project);
}),
);
}
} good! this method should not exist! why did i do this 😆 ! you only need to warm the GraphQLCache for the project if it hasn't been already. so, this cache/config/langauge service init step could be called once every time you open a file in a project that has not initialized before. This way, if you only open a file in one of your graphql config projects, only the cache for that project is built, and if enabled, only the SDL definition lookup for that project is cached in your fs |
I think it's possible if we do this, or something you feel is even more optimal, #2459 we can hopefully close as well, which is terrible, vscode-crashing perf issues on multi-project caused by this method! |
I have never used discord, but I just installed it and joined the channel! And thank you for your very thorough explanation! |
@Foo-x if you want to add that optimisation, then sure! I will reach out on discord |
@@ -89,58 +89,48 @@ function toPosition(position: VscodePosition): IPosition { | |||
return new Position(position.line, position.character); | |||
} | |||
|
|||
export class MessageProcessor { | |||
class WorkspaceMessageProcessor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Brilliant! An elegant solution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you be interested in separating the WorkspaceMessageProcessor
into a separate file? the less cognitive overhead, the more useful it is as a reference implementation, the more accessible it is to contributors!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your review!
Separated to new file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything here looks good to go! Thank you @Foo-x for helping with such a comprehensive PR!
Looking forward to more collaboration when you're able! 🚀
This reverts commit 5827977.
Introduces multi-root workspaces support using a single language server instance! Adds a few optimisations, tests, etc as well. This had previously been merged in a way that caused issues, but this should resolve those issues. Revert "Revert "feat: support vscode multi-root workspaces (#2594)" (#2612)" (#2616)
Closes #2379
I reffered to the following official implementation.
https://github.com/microsoft/vscode-extension-samples/blob/main/lsp-multi-server-sample/client/src/extension.ts
graphql-language-service-server
will be started for each folders, and the corresponding schema is used for each.The schema for
packages/app
folder hasfoo
.The schema for
packages/api
folder does not havefoo
.StatusBarItem
andOutputChannel
will be shared by all folders and updated according to the active editor.