Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/dteam-top/vscode-page

A light-weight page micro framework for vscode webview.
https://github.com/dteam-top/vscode-page

vscode vscode-extension vscode-webview

Last synced: about 2 months ago
JSON representation

A light-weight page micro framework for vscode webview.

Awesome Lists containing this project

README

        

# vscode-page

[![Code Style: Google](https://img.shields.io/badge/code%20style-google-blueviolet.svg)](https://github.com/google/gts)

[![NPM](https://nodei.co/npm/vscode-page.png?compact=true)](https://nodei.co/npm/vscode-page/)

vscode-page is a light-weight page micro framework for vscode webview, it could accelerate Vs Code Extension Webview development.

## Features

- abstract the communication between html page and WebviewPanel, developers can focus on business logic.
- built-in template engine, with [handlebars.js](https://www.npmjs.com/package/handlebars).
- message mapping, a simple way to organize page logic and view.
- baseUrl support, relative paths can be used in html page.

## Installing

```shell
npm install vscode-page
```

## Usage

vscode-page simplifies Webview development with following steps:

1. define messages between html page and vscode.WebviewPanel.
1. develop html page and js functions inside that page.
1. define MessageMappings.
1. register a command to create (or show) WebviewPanel with the MessageMappings defined in step 3.

The whole architecture is shown below:

![vscode-page architecture](images/architecture.png)

Also, there is [a demo project](example) to show its usage. Before check it, please read the following first.

### Messaging

As described in vscode extension guide, html page and WebviewPanel can post messages each other. To standardize this communication, vscode-page defines two message formats.

#### js -> WebviewPanel

The message json format :

- command, an indexed value for a command handler defined in a MessageMapping.
- parameters (optional), an json argument passed to that command handler.

Here is an example:

```json
{
"command": "showExtension",
"parameters": {
"repo": repo,
"extId": extId,
"installed": installed
}
}
```

#### WebviewPanel -> js

The message json format :

- command, if ending with "Response", it is a response of the prefix. Such as "showExtensionResponse" is response of "showExtension".
- contents (optional), a content array. Each item has following keys:
- id, element id in a html page.
- body, innerHtml (generated by the template defined in a MessageMapping) of the element pointed by id.
- result (optional), return value of the "\${command}" handler.

Here is an example:

```json
{
"command": "showExtensionResponse",
"contents": [
{ "id": "title", "body": "Repo / Extension" },
{
"id": "content",
"body": "...."
}
]
}
```

### HTML Page

In order to initialize correctly, for each html page, please insert the following two lines in \:

```

"{{init}}"

```

Here is the explaination:

- {{base}} will be replaced by "path.join(context.extensionPath, root)", then relative paths can be used in that page.
- {{init}} will be replaced by initEventListener function definition, which defines an EventListener receiving messages from WebviewPanel.

Then it can be invoked to add an event listener to html page as below:

```javascript
initEventListener();
```

The default implementation will only process messages ending with "Response" and use contents as innerHtml of selected elements.

For other messages, a customized function can be passed to initEventListener as below:

```javascript
initEventListener(message => {...});
```

The message has following key:

- result, return value of a command handler.

### MessageMappings

A MessageMapping defines:

- command, the value of "command" field in message posted by js function.
- handler, a function for the command above, its signature is below and the parameters is the value of "parameters" in the same message from js function.

```typescript
(parameters?: any) => Promise;
```

- templates (optional), a template array for views of response of the command. Each item has the following keys:
- id, element id in html page.
- content, a inline handlebars template, it is optional.
- contentUrl, a url to an external handlebars template, it is optional.
- forward (optional), similar to request-forward pattern in web development, a MessageMapping the request flow will go.

NOTE:

- either "content" or "contentUrl" MUST be shown in a MessageMapping, not both.
- both of "templates" and "forward" are optional, but if being used, only one of them can be shown in a MessageMapping.

Here is a MessageMappings example: [home.ts](example/src/home.ts)

### createOrShowPage

To create or show a WebviewPanel, invoke function createOrShowPage like beblow (from [extension.ts](example/src/extension.ts) in example):

```typescript
createOrShowPage(
'name',
'ext.home',
'Sample Page',
'pages',
'home.html',
context,
messageMappings
);
```

The signature of createOrShowPage:

```typescript
export function createOrShowPage(
name: string,
viewType: string,
title: string,
base: string,
page: string,
context: vscode.ExtensionContext,
messageMappings: MesssageMaping[]
);
```

Each argument:

- name, a named index of the WebviewPanel created.
- viewType and title, both of them will be passed to vscode.window.createWebviewPanel.
- base, a relative path to \ in html page.
- page, a path to html file.
- context, vscode.ExtensionContext.
- messageMappings, MesssageMaping array defined, check examples in [home.ts](example/src/home.ts).

## Requirements

vscode-page is a tool for [vscode](https://code.visualstudio.com/) extension development and uses [handlebars.js](https://www.npmjs.com/package/handlebars) as its template engine.

So, please install **vscode** and **handlebars** first.

## Development

For local debugging, please run the following command under the directory of vscode-page project:

```shell
npm link
```

Then, in the project using vscode-page, please run the following command:

```shell
npm link vscode-page
```

NOTE:

The linked package in application will use its own node_modules, so if you defined your own handlebars helper in application, vscode-page can not find it.

```shell
app
|- node_modules
|- vscode-page <-- project linked by "npm link"
| ├─ node_modules
| | |- handlebars.js <-- used by vscode-page
|
|- handlebars.js <-- you defined helper in it
```

I can not find an easy way to fix it, only find the following steps. If you have any good idea, please let me know.

- "npm pack" in vscode-page project.
- "npm install local-package" in your application.

## Resources

- [使用 vscode-page 简化 vscode 插件的 Webview 开发](https://blog.dteam.top/posts/2020-03/simplify-vscode-webview-development-with-vscode-page.html)
- [Simplifying VS Code Webview Development with vscode-page](https://dev.to/foxgem/simplifying-vs-code-webview-development-with-vscode-page-13c3)

## Known Issues

Please visit [issues](https://github.com/DTeam-Top/vscode-page/issues) page to submit new issues or check known issues.

## Release Notes

### 0.0.1

First release.

## License

vscode-page is released under the Apache License 2.0 license.