Creating a personal TypeScript language service extension in Visual Studio Code

Currently, I am working on developing a TSserver plugin in VSCode and struggling to get the server to load my plugin.

I have experimented with setting the path in tsconfig.json to both a local path and a path to node_modules, but it still isn't working as expected.

To demonstrate the issue, I have created a very minimal project that should ideally run the plugin. You can find the project at https://github.com/Spensaur-K/minimal-tsserver-plugin

Despite my efforts, the server fails to load the plugin. It doesn't log any messages from the plugin or crash even when I intentionally introduce errors into the plugin code.

Answer №1

My experience with loading a custom plugin on TS Server from a file has been quite challenging:

  1. To start, enabling workspace configuration using local TypeScript is necessary:

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
}

Utilizing local TypeScript is vital as it ensures that the plugin is found within the correct directory by TS Server. Attempting to use global TypeScript leads to complications due to differences in working directories.

Enabling verbose logging may not be essential, but it helps in debugging and ensuring no details are missed during the process of setting up the plugin.

Including workspace TypeScript version prompt is also beneficial for maintaining consistency across projects.

  1. The next step involves creating your plugin within the project's node_modules/plugin directory.

This process may seem suboptimal, as having the source code in the node_modules folder can be inconvenient. However, due to TS Server's working directory structure, there aren't straightforward alternatives at the moment.

It appears that writing the plugin directly in TypeScript without transpilation is not feasible.

  1. Finally, configuring TS Server to utilize the plugin and restarting it is required.

Updating the tsconfig.json file with the plugin information and restarting TS Server is necessary to ensure successful integration.

If anyone has insights on improving this process or addressing the challenges mentioned, any suggestions would be greatly appreciated!

Edit:

An improvement suggestion is provided to streamline the process by adjusting the plugin file referencing methods. However, further enhancements are sought to simplify the setup without relying heavily on the node_modules directory.

A bug report has been submitted for consideration: https://github.com/microsoft/TypeScript/issues/43124

Answer №2

For TS Server plugins located within the node_modules directory to be loaded, it is necessary to use a workspace version of TypeScript and ensure that the plugin is specified in the project's tsconfig.json. Attempting to use a relative path for the plugin may result in failure as well.

To test this setup:

  1. Install minimal-tsserver-plugin under node_modules
  2. Employ the workspace version of TypeScript
  3. In your tsconfig file, include:

    {
      "compilerOptions": {
        "plugins": [
          {
            "name": "minimal-tsserver-plugin"
          }
        ]
      }
    }
    

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A guide on transferring received data from dataService within the parent component to the child component in Angular2

Within the context of my application, there exists a parent component named app-parent and a child component called app-child. In app-parent, I retrieve data from a DataService. @Component({ selector: 'app-parent', providers: [DataService] ...

Error TS2403: All variable declarations following the initial declaration must be of the same type in a React project

While developing my application using Reactjs, I encountered an error upon running it. The error message states: Subsequent variable declarations must have the same type. Variable 'WebGL2RenderingContext' must be of type '{ new (): WebGL2 ...

UI not reflecting updated form validation after changes made

Currently, I have a situation where I am passing a form from the Parent component to the Child component. All the validations are being handled in the Parent component and the Child component is simply rendering it. However, there is a specific field calle ...

Using Angular BehaviorSubject in different routed components always results in null values when accessing with .getValue or .subscribe

I am facing an issue in my Angular application where the JSON object saved in the service is not being retrieved properly. When I navigate to another page, the BehaviorSubject .getValue() always returns empty. I have tried using .subscribe but without succ ...

What is the correct way to bring in a utility in my playwright test when I am working with TypeScript?

I am working on a basic project using playwright and typescript. My goal is to implement a logger.ts file that will manage log files and log any logger.info messages in those files. To set up my project, I used the following commands and created a playwri ...

Tips for correctly specifying the types when developing a wrapper hook for useQuery

I've encountered some difficulties while migrating my current react project to typescript, specifically with the useQuery wrappers that are already established. During the migration process, I came across this specific file: import { UseQueryOptions, ...

Deactivating an emitted function from a child component in Angular 4

There is a main component: @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { funcBoo():void{ alert("boo"); //return fal ...

Manipulating CSS Class Properties Using JavaScript

In my JavaScript application, there is a functionality that loads a list of items for users to click and view detailed information in a separate div on the page. Users should be able to interact with and make modifications to these individual item overview ...

The response code in the API remains 200 despite setting the status code to 204 in NestJS

I have developed an API that needs to return a 204 - No Content Response import { Controller, Get, Header, HttpStatus, Req, Res } from '@nestjs/common'; import { Response } from 'express'; @Get("mediation-get-api") @Head ...

Error occurred while creating a new instance of a generic object

I´m encountering a TypeError: type is not a constructor when attempting to convert API data into Frontend DTOs. The transformation method is as follows: transform<T>(entities: any[]) { const tableDtos = new Array<T>(); for (const ent ...

Typescript - optional type when a generic is not given

I am hoping for optionalFields to be of type OptionalFieldsByTopic<Topic> if a generic is not provided, or else OptionalFieldsByTopic<T>. Thank you in advance for the assistance. export interface ICreateItem<T extends Topic = never> { // ...

Objects in the array are failing to sort in the expected sequence

I am facing an issue with sorting an array of objects by a date property using the lodash function orderBy. I have tried to sort it in both ascending and descending order. var searchObj = [{id: 1, postDate: '2/24/2016 5:08 PM'}, ...

Unable to locate the name 'Cheerio' in the @types/enzyme/index.d.t file

When I try to run my Node application, I encounter the following error: C:/Me/MyApp/node_modules/@types/enzyme/index.d.ts (351,15): Cannot find name 'Cheerio'. I found a suggestion in a forum that recommends using cheerio instead of Cheerio. H ...

Converting HTML templates into AMD modules using grunt-ts

When using the grunt-ts plugin and specifying the html: ["*.tpl.html"] option, it converts *.tpl.html files into *.tpl.html.js files at the end of the process, creating a global var. Is there a way to configure grunt-ts to output the final .js file in a d ...

The error "ReferenceError: window is not defined" occurs when calling client.join() due to

I am looking to create a video call application using React and Next.js with the AgoraRTC SDK. After successfully running AgoraRTC.createClient(), AgoraRTC.createStream(), and client.init(), I encountered an error when trying to execute client.join(). The ...

Utilizing a Function's Parameter Type in TypeScript: A Beginner's Guide

Currently, I am creating a custom method that wraps around Angular's HttpClient service. I want users to have the ability to pass in options, but I am struggling to find the proper way to reference that type in my method parameter definition. For exa ...

Error with React, key must be unique. What's the issue?

What is causing the issue with unique keys? To resolve the problem, ensure that each list item has a unique key. For example, if we have x_values = {'male':[1,2,3], 'female':[2,3,4]} the keys should be : 'mean-male', ' ...

Leveraging Interface in Protractor Testing

As a newcomer to Typescript and Protractor, I have been working with reusable code in various classes. Instead of importing each library class separately into my test class, I am trying to find a way to import just one class or interface that will contai ...

Guide to turning off the previous button in FullCalendar using Angular 7 and TypeScript

Can someone help me with disabling the previous button on FullCalendar if I go back 2 months? For example, if it's currently April and I navigate to February, I want the previous button to be disabled. I have FullCalendar implemented, but all the sol ...

Ways to employ data binding for extracting a user-input value and performing multiplication operations with the enclosed {{ ...}} tags

My API response includes the price of a product, which is represented as {{price}} I have a system where I can add or reduce the number of products: <div class="number-input"> <h2>Price: {{price }}</h2> <button oncli ...