Available today in the 17.4 public release, Visual Studio has revamped its ESLint support! The new linting experience includes:
- Quick actions and fixes, which allow you to auto-fix errors or disable ESLint rules on a single line or an entire file.
- A guiding installation wizard that will help you set up your ESLint configuration and dependencies based on your project.
But the main purpose of this post is not to list all of the cool things that the new linting service provides, but to tell you a little bit about the story behind it. I joined Microsoft at the beginning of 2022, and as an eager software engineer on the fantastic TypeScript tooling team, I was curious about what my first large project might be.
An LSP extension inspired from vscode-eslint
The goal was for the linting experience in Visual Studio to be on par with the one in VS Code. The editor’s support for disabling ESLint rules, auto fixing errors, and the settings available for tuning the linter’s behavior are highly beloved features by VS Code users.
The LSP-based architecture of vscode-eslint meant that our goal was feasible: Visual Studio’s linting integration could be of the same quality as VS Code’s, since they could use the same server behind the scenes. We still had to write the Visual Studio client, which would make those linting squiggles show up in the editor.
I don’t want to bore you with all the technical details (mostly because they involve me debugging JSON error responses), but I do want to mention some of the things we learned from this experience:
- Extensions should feel natural to its host. The VS Code extension relies on workspace configurations for storing local linting settings, but most Visual Studio developers use projects and solutions to organize their code. We then decided to use project properties for these local settings, respecting the IDE’s essence.
- Documentation is key. From the LSP specification listing the relevant requests that our client had to handle, to the fantastic extensions from our dear Mads that illustrate how to use several of Visual Studio’s extensibility services. Implementing this feature motivated me to also give back to the extensibility community, and now I try to improve existing documentation (or add new one) that captures the things I learn.
- LSP extensibility is amazing. It might be a bit of a learning curve to get started, but it abstracts the specifics of the editor’s implementation (no need to implement a custom ITagger to provide error squiggles!), allowing you to build a reusable and more compact extension.
Using the new linting service
To get started with ESLint in your project, you’ll first need to install the npm module by running
npm install –dev eslint in the command line. You might need to install additional linting plugins; for example, you may need TypeScript ESLint, which enables ESLint to run on TypeScript code and includes rules that are specific to the extra type information.
.eslintrc file to customize your linting configuration. The ESLint website has great documentation about how to use this file.
And that’s it! You should now be able to see error squiggles when your code doesn’t follow your linting rules:
By right-clicking on the squiggle and viewing the available quick actions, you’ll be able to disable the error or fix it!
You can try out the new linting experience in Visual Studio 17.4 (note that linting in Vue and HTML will be available in the next release). Make sure to review the documentation for detailed instructions on the required setup, and please submit a feedback ticket if you encounter any issues or have an idea of what other linting enhancements you would like to see in Visual Studio.
Enjoy your squiggles!
This is fascinating to read about. I worked on a project for over two decades which had some files using my own custom syntax, and I always low-key hoped to eventually add syntax highlighting and IntelliSense for them. Sadly that project is no more and I’ll never actually get to do it, but my interest in the topic lives on.
I’m curious about the division of responsibility between client and server when it comes to LSP: I’d naively imagined that once an LSP service existed, it could be used immediately by any IDE which understands the protocol, but from your article it sounds like that’s at best an oversimplification, if not outright wrong. You mentioned management and storage of user settings, which makes sense; are there other areas where the IDE client needs customized code for each individual LSP?
Glad to hear that you enjoyed the post!
To answer your question, another good example where LSP client code is often specific to each editor is the display of diagnostics. Notice how in VS Code errors in the “Problems” pane can be displayed in a tree or table view, and the information about the error (like the code in location) is shown in a different way for each view. In VS, diagnostics are listed in the error list, and there are extra columns that don’t appear in VS Code (like the “Project” and “Suppression state” columns). Editors can offer extensions like this to accommodate for these extra features.
This really rocks!
No more waiting 20 seconds for eslint updates in the editor. Thank a lot for your work.