Reputation: 31
I am trying to develop a TSserver plugin in VSCode but I can not get the server to load my plugin
I have tried setting the path in tsconfig.json to be a local path and a path to node_modules
This is a very minimal project that I think should run the plugin https://github.com/Spensaur-K/minimal-tsserver-plugin
The server doesn't load the plugin. It doesn't log messages in the plugin or crash if I put an error in the plugin
Upvotes: 3
Views: 2353
Reputation: 10617
The only way I have been able to make a custom plugin load in TS Server while being served from a file:
npm i typescript
package.json
:
{
"dependencies": {
"typescript": "^4.2.3"
}
}
.vscode/settings.json
{
"typescript.tsdk": "./node_modules/typescript/lib",
// ~/.config/Code/logs/**/tsserver.log
"typescript.tsserver.log": "verbose",
"typescript.enablePromptUseWorkspaceTsdk": true
}
Using local TypeScript is important, because TypeScript will look for the plugin by package name in node_modules
in the working directory of TS Server and up. If attempted to use global TypeScript (/usr/local/lib/node_modules/typescript/lib
), the working directory of tsserver
will be thereabout and your plugin will be nowhere near that path.
Using verbose seems optional, because all of the plugin-loading related messages in the TS Server seem to be info level, but I enabled it to make sure I don't miss absolutely anything as debugging this is contrived enough as it is: to view the logs, press Cmd+Shift+P when in a TS/JS file and Select TypeScript: Show Open TS Server Log.
Enabling the prompt for workplace TypeScript version is also optional, it helps to not forget to do it manually as you'd otherwise have to by going Cmd+Shift+P when in a TS/JS file and selecting TypeScript: Select TypeScript Version and switching that to the workspace version configured in .vscode/settings.json
.
node_modules/plugin
in your project directoryThis is the suboptimal part, I hate to have the source code for the plugin in node_modules
, but I have not found the way to move it out, because TS Server's working directory is now in node_modules
of your project directory and the next directory up is the node_directory
of the parent of your project directory and so on. I don't know how to make it so that your plugin code does not need to be in this chain.
node_modules/plugin/package.json
:
{
"name": "plugin"
}
node_modules/plugin/index.js
:
module.exports = function init(modules) {
function create(info) {
const service = info.languageService;
info.project.projectService.logger.info(
"Started custom plugin"
);
return service;
}
return { create };
}
I don't think it is possible to author the plugin in TypeScript directly without having to transpile.
tsconfig.json
:
{
"compilerOptions": {
"plugins": [
{
"name": "plugin"
}
]
}
}
The name cannot be a file path (https://github.com/microsoft/TypeScript/issues/18623) so we refer to the plugin by a Node package name here and thus all the shenanigans with placing the plugin source code within the node_modules
chain leading up the to the TS Server working directory.
To restart TS Server, go to a TS/JS file and press Cmd+Shift+P and select TypeScript: Restart TS Server. Then press Cmd+Shift+P again and select TypeScript: Open TS Server Log.
You should see something like this then (…
stands for your project directory):
Info 24 [09:59:19.919] Enabling plugin plugin from candidate paths: /…/node_modules/typescript/lib/tsserver.js/../../..,/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/typescript-language-features
Info 25 [09:59:19.919] Loading plugin from /…/node_modules/typescript/lib/tsserver.js/../../.. (resolved to /…/node_modules/node_modules)
Info 26 [09:59:19.923] Started custom plugin
Info 27 [09:59:19.923] Plugin validation succeded
If anyone knows how to make the plugin load from your project directory directly and not from node_modules
or how to use the global TypeScript install instead of a local one, I'm all ears!
Edit:
One improvement that can be made is to change node_modules/plugin/index.js
to this:
module.exports = require('../../plugin.js');
And move the code that was there previously to plugin.js
in your project directory. I'd prefer there was a way to do all this without any node_modules
directory in my project directory, but alas.
I have opened a TypeScript bug repor for this: https://github.com/microsoft/TypeScript/issues/43124
Upvotes: 3
Reputation: 65273
TS Server plugins under node_modules
are only loaded if you are using a workspace version of typescript and the plugin is listed in the tsconfig.json
for your project. Using a relative path for the plugin may also not work.
To run the example:
minimal-tsserver-plugin
under node_modules
In your tsconfig, have:
{
"compilerOptions": {
"plugins": [
{
"name": "minimal-tsserver-plugin"
}
]
}
}
Upvotes: 1