Unseen
Unseen

Reputation: 287

How to make acquireVsCodeApi available in vscode webview [React]

I'm trying to develop a new extension for vscode based on Webview but I am running into problems with posting messages from client to extension. As a starter, I used this repo and I am following these steps from Microsoft.

As you can see in the example we have:

(function() {
            const vscode = acquireVsCodeApi();

My problem is that in my react app the acquireVsCodeApi is like it doesn't exist. I tried multiple ways eg. in componentDidMount lifecycle but no luck.

This user seems to be able to run it but parts of his app are missing so is not clear to me.

Does anyone have an idea of how to use acquireVsCodeApi() with React or a code snippet that can help?

Regards

Upvotes: 7

Views: 8922

Answers (4)

Amith B
Amith B

Reputation: 365

The function acquireVsCodeApi() will be by default available when the app runs inside vs code. But you may get a ts error or a eslint error while compiling React or any other library. Just ignore them with ts ignore or es lint disable comments and then proceed with your code.

function App {
    // eslint-disable-next-line no-undef
    const vscode = acquireVsCodeApi();
    ...
}

// or

function App {
    // @ts-ignore
    const vscode = acquireVsCodeApi();
    ...
}

Upvotes: 0

Kagurazaka
Kagurazaka

Reputation: 61

Webpack + NPM version

This NPM version uses two packages: vscode-webview and @types/vscode-webview. The @types/vscode-webview is reasonably recent, but vscode-webview has been abandoned in an immature state. While the code 'webpack's ok, it is somewhat dubious.

Your repository uses typescript, and so you can install a type declaration from npm to allow your typescript checker to determine the correct interface for the vscode api.

A type declaration file is available for vscode-webview on npm.: npm install @types/vscode-webview

Then, in your code, you would put in your imports:

import "vscode-webview"

This is a little different from the usual import * from "vscode-webview" as the author has used a global scoped declare to match the globally scoped acquireVsCodeApi function.

Link on npm: [@types/vscode-webview] https://www.npmjs.com/package/@types/vscode-webview

To avoid the dubious package:

Copy the contents of @types/vscode-webview into a local file, and point your imports at your local file.

Upvotes: 5

Limboer
Limboer

Reputation: 414

Similar to @Unseen's answer, what i did is create a global.d.ts file, and declare vscode type there.

type VSCode = {
  postMessage(message: any): void;
  getState(): any;
  setState(state: any): void;
};

declare const vscode: VSCode;

In this case you can access vscode in any file. Example: https://github.com/hacker0limbo/vscode-webview-react-boilerplate/blob/master/app/global.d.ts

Upvotes: 3

Unseen
Unseen

Reputation: 287

Ok, so first you need to assign it into a variable in webview content in a script eg: https://github.com/shinhwagk/vscode-note/blob/be2aabf2812a9b6200be971425535024440dbd88/src/panel/notesPanelView.ts#L32

and then in typescript, it has to be an interface

interface vscode {
    postMessage(message: any): void;
}

declare const vscode: vscode;

const addCategory = () => () => vscode.postMessage({ command: 'add-category' });

Solution came from here: https://github.com/shinhwagk/vscode-note/blob/be2aabf2812a9b6200be971425535024440dbd88/src/webview/index.tsx#L10

Upvotes: 6

Related Questions