Skip to content

Commit

Permalink
Create React-based hello-world Sample Extensions (microsoft#41)
Browse files Browse the repository at this point in the history
Description of changes

Adds two React-based implementations (one using Create React App and another using Vite) of the default `hello-world` sample extension to demonstrate how to use and create a React-based webview extension that uses the Webview UI Toolkit.
  • Loading branch information
hawkticehurst authored Jan 29, 2022
1 parent edbe8bc commit c9c0237
Show file tree
Hide file tree
Showing 154 changed files with 53,251 additions and 12 deletions.
55 changes: 47 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,59 @@ Each sample is a self contained extension and demonstrates some aspect of the to

## Prerequisites

You need to have [Node and NPM](https://nodejs.org/en/) installed on your system to run the examples. It is recommended to use the Node version used for VS Code development itself which is documented [here](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites).
You need to have [Node and NPM](https://nodejs.org/en/) installed on your system to run the samples. It is recommended to use the Node version used for VS Code development itself which is documented [here](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites).

## Usage

Follow the instructions in the `README` file of the desired sample extension.

## Samples
### Default Samples

| Sample Extension | Description |
| ------------------------------------ | --------------------------------------------------------------------------------- |
| [all-components](./all-components) | Demonstrates every component in the Webview UI Toolkit. |
| [hello-world](./hello-world) | A basic hello world starter extension. |
| [notepad](./notepad) | A simple note taking extension that leverages the VS Code TreeView API. |
| [weather-webview](./weather-webview) | Demonstrates the toolkit being used within a Webview View (i.e. VS Code sidebar). |
A set of sample extensions using vanilla HTML, CSS, and JavaScript to render the Webview UI.

| Sample Extension | Description |
| -------------------------------------------- | --------------------------------------------------------------------------------- |
| [all-components](./default/all-components) | Demonstrates every component in the Webview UI Toolkit. |
| [hello-world](./default/hello-world) | A basic hello world starter extension. |
| [notepad](./default/notepad) | A simple note taking extension that leverages the VS Code TreeView API. |
| [weather-webview](./default/weather-webview) | Demonstrates the toolkit being used within a Webview View (i.e. VS Code sidebar). |

### React Samples

A set of sample extensions using React to render the Webview UI.

| Sample Extension | Description |
| ---------------------------------------------| --------------------------------------------------------------------- |
| [hello-world-cra](./react/hello-world-cra) | A basic hello world starter extension using React + Create React App. |
| [hello-world-vite](./react/hello-world-vite) | A basic hello world starter extension using React + Vite. |

### Svelte Samples

A set of sample extensions using Svelte to render the Webview UI.

| Sample Extension | Description |
| ------------------------| ----------- |
| _Coming in the future!_ | |

### Vue Samples

A set of sample extensions using Vue to render the Webview UI.

| Sample Extension | Description |
| ------------------------| ----------- |
| _Coming in the future!_ | |

### Angular Samples

A set of sample extensions using Angular to render the Webview UI.

| Sample Extension | Description |
| ------------------------| ----------- |
| _Coming in the future!_ | |

### Other Samples

Don't see a demonstration for your desired framework, API, use case, and so on? Feel free to open an issue and request it!

## Contributing

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This sample extension demonstrates every component in the Webview UI Toolkit for

```bash
# Copy sample extension locally
npx degit microsoft/vscode-webview-ui-toolkit-samples/all-components all-components
npx degit microsoft/vscode-webview-ui-toolkit-samples/default/all-components all-components

# Navigate into sample directory
cd all-components
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion hello-world/README.md → default/hello-world/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This is the sample extension that goes along with the Webview UI Toolkit [Gettin

```bash
# Copy sample extension locally
npx degit microsoft/vscode-webview-ui-toolkit-samples/hello-world hello-world
npx degit microsoft/vscode-webview-ui-toolkit-samples/default/hello-world hello-world

# Navigate into sample directory
cd hello-world
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion notepad/README.md → default/notepad/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This sample extension showcases the toolkit in the context of a simple notepad e

```bash
# Copy sample extension locally
npx degit microsoft/vscode-webview-ui-toolkit-samples/notepad notepad
npx degit microsoft/vscode-webview-ui-toolkit-samples/default/notepad notepad

# Navigate into sample directory
cd notepad
Expand Down
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This sample extension demonstrates the Webview UI Toolkit for Visual Studio Code

```bash
# Copy sample extension locally
npx degit microsoft/vscode-webview-ui-toolkit-samples/weather-webview weather-webview
npx degit microsoft/vscode-webview-ui-toolkit-samples/default/weather-webview weather-webview

# Navigate into sample directory
cd weather-webview
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
18 changes: 18 additions & 0 deletions react/hello-world-cra/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/naming-convention": "warn",
"@typescript-eslint/semi": "warn",
"curly": "warn",
"eqeqeq": "warn",
"no-throw-literal": "warn",
"semi": "off"
},
"ignorePatterns": ["webview-ui/**"]
}
22 changes: 22 additions & 0 deletions react/hello-world-cra/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build
/dist

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
13 changes: 13 additions & 0 deletions react/hello-world-cra/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"quoteProps": "consistent",
"jsxSingleQuote": false,
"trailingComma": "es5",
"bracketSpacing": true,
"jsxBracketSameLine": true,
"arrowParens": "always"
}
7 changes: 7 additions & 0 deletions react/hello-world-cra/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"dbaeumer.vscode-eslint"
]
}
34 changes: 34 additions & 0 deletions react/hello-world-cra/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// A launch configuration that compiles the extension and then opens it inside a new window
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
},
{
"name": "Extension Tests",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
],
"outFiles": [
"${workspaceFolder}/out/test/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
}
]
}
11 changes: 11 additions & 0 deletions react/hello-world-cra/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
}
20 changes: 20 additions & 0 deletions react/hello-world-cra/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
12 changes: 12 additions & 0 deletions react/hello-world-cra/.vscodeignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.vscode/**
.vscode-test/**
out/test/**
src/**
webview-ui/**
.gitignore
.yarnrc
vsc-extension-quickstart.md
**/tsconfig.json
**/.eslintrc.json
**/*.map
**/*.ts
37 changes: 37 additions & 0 deletions react/hello-world-cra/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Hello World (React + Create React App)

This is an implementation of the default [Hello World](../default/hello-world) sample extension that demonstrates how to set up and use a [React](https://reactjs.org/) + [Create React App](https://create-react-app.dev/) + [Webview UI Toolkit](https://github.com/microsoft/vscode-webview-ui-toolkit) webview extension.

![A screenshot of the sample extension.](./assets/helloworld-screenshot.png)

## Documentation

For a deeper dive into how this sample works, read the guides below.

- [Extension structure](./docs/extension-structure.md)
- [Extension commands](./docs/extension-commands.md)
- [Extension development cycle](./docs/extension-development-cycle.md)

## Run The Sample

```bash
# Copy sample extension locally
npx degit microsoft/vscode-webview-ui-toolkit-samples/react/hello-world-cra hello-world

# Navigate into sample directory
cd hello-world

# Install dependencies for both the extension and webview UI source code
npm run install:all

# Build webview UI source code
npm run build:webview

# Open sample in VS Code
code .
```

Once the sample is open inside VS Code you can run the extension by doing the following:

1. Press `F5` to open a new Extension Development Host window
2. Inside the host window, open the command palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and type `Hello World`
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions react/hello-world-cra/docs/extension-commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Extension commands

A quick run down of some of the important commands that can be run when at the root of the project.

```
npm run install:all Install package dependencies for both the extension and React webview source code.
npm run start:webview Runs the React webview source code in development mode. Open http://localhost:3000 to view it in the browser.
npm run build:webview Build React webview source code. Must be executed before compiling or running the extension.
npm run compile Compile VS Code extension
```
30 changes: 30 additions & 0 deletions react/hello-world-cra/docs/extension-development-cycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Extension development cycle

The intended development cycle of this React-based webview extension is slightly different than that of other VS Code extensions.

Due to the fact that the `webview-ui` directory holds a self-contained React application we get to take advantage of some of the perks that that enables. In particular,

- UI development and iteration cycles can happen much more quickly by using Create React App (CRA)
- Dependency management and project configuration is hugely simplified

## UI development cycle

Since we can take advantage of the much faster CRA dev server, it is encouraged to begin developing webview UI by running the `npm run start:webview` command and then editing the code in the `webview-ui/src` directory.

_Tip: Open the command palette and run the `Simple Browser` command and fill in `http://localhost:3000/` when prompted. This will open a simple browser environment right inside VS Code._

### Message passing
If you need to implement message passing between the webview context and extension context via the VS Code API, a helpful utility is provided in the `webview-ui/src/utilities/vscode.ts` file.

This file contains a utility wrapper around the `acquireVsCodeApi()` function, which enables message passing and state management between the webview and extension contexts.

This utility also enables webview code to be run in the CRA dev server by using native web browser features that mock the functionality enabled by acquireVsCodeApi. This means you can keep building your webview UI with the CRA dev server even when using the VS Code API.

### Move to traditional extension development
Once you're ready to start building other parts of your extension, simply shift to a development model where you run the `npm run build:webview` command as you make changes, press `F5` to compile your extension and open a new Extension Development Host window. Inside the host window, open the command palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and type `Hello World`.

## Dependency management and project configuration

As mentioned above, the `webview-ui` directory holds a self-contained and isolated React application meaning you can (for the most part) treat the development of your webview UI in the same way you would treat the development of a regular React application.

To install webview-specific dependencies simply navigate (i.e. `cd`) into the `webview-ui` directory and install any packages you need or set up any React specific configurations you want.
40 changes: 40 additions & 0 deletions react/hello-world-cra/docs/extension-structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Extension structure

This section provides a quick introduction into how this sample extension is organized and structured.

The two most important directories to take note of are the following:

- `src`: Contains all of the extension source code
- `webview-ui`: Contains all of the webview UI source code

## `src` directory

The `src` directory contains all of the extension-related source code and can be thought of as containing the "backend" code/logic for the entire extension. Inside of this directory you'll find the:

- `panels` directory
- `utilities` directory
- `extension.ts` file

The `panels` directory contains all of the webview-related code that will be executed within the extension context. It can be thought of as the place where all of the "backend" code for each webview panel is contained.

This directory will typically contain individual TypeScript or JavaScript files that contain a class which manages the state and behavior of a given webview panel. Each class is usually in charge of:

- Creating and rendering the webview panel
- Properly cleaning up and disposing of webview resources when the panel is closed
- Setting message listeners so data can be passed between the webview and extension
- Setting the initial HTML markdown of the webview panel
- Other custom logic and behavior related to webview panel management

As the name might suggest, the `utilties` directory contains all of the extension utility functions that make setting up and managing an extension easier. In this case, it contains `getUri.ts` which contains a helper function which will get the webview URI of a given file or resource.

Finally, `extension.ts` is where all the logic for activating and deactiving the extension usually live. This is also the place where extension commands are registered.

## `webview-ui` directory

The `webview-ui` directory contains all of the React-based webview source code and can be thought of as containing the "frontend" code/logic for the extension webview.

This directory is special because it contains a full-blown React application which was created using the TypeScript [Create React App](https://create-react-app.dev/) template. As a result, `webview-ui` contains its own `package.json`, `node_modules`, `tsconfig.json`, and so on––separate from the `hello-world` extension in the root directory.

This strays a bit from other extension structures, in that you'll usually find the extension and webview dependencies, configurations, and source code more closely integrated or combined with each other.

However, in this case, there are some unique benefits and reasons for why this sample extension does not follow those patterns such as easier management of conflicting dependencies and configurations, as well as the ability to use the CRA dev server, which drastically improves the speed of developing your webview UI, versus recompiling your extension code every time you make a change to the webview.
Loading

0 comments on commit c9c0237

Please sign in to comment.