简介
本文专门针对那些喜欢名为VS Code的代码编辑器的人,该编辑器一直被低估且未被充分使用。
代码编辑器内部有一个扩展部分,可以在编写代码片段(自动完成)、调试、主题等更有用的扩展时提供额外的帮助。
例如,Postman VS Code 扩展使您能够直接从 Visual Studio Code 在 Postman 中开发和测试 API。
在上面的扩展中,显示的 UI 位于 VS Code 内部,这得益于 Postman 扩展的帮助。因为它似乎也是代码编辑器不可或缺的一部分,但可以肯定的是,这是仅使用html、css和javascript制作的,任何人都可以轻松制作。
为了确保您只需按 ,Ctrl + Shift + P
然后选择Developer: Toggle Developer Tools
显示 VS Code 中的开发工具。
正如上面的 gif 中提到的,人们可以像检查任何网页一样轻松地检查任何扩展。现在到了重要的部分,如何进行这样的扩展。
让我们从它开始......
了解扩展创建
为了创建扩展,VS Code 使用名为Yeoman和Code-Generator 的cli 工具。
在开始之前,您需要安装 npm 并了解 Node 的基本知识。
全局安装包
npm install --global yo generator-code
启动扩展安装
yo code
之后,您将看到这个 Yeomen 扩展菜单
_-----_ ╭──────────────────────────╮
| | │ Welcome to the Visual │
|--(o)--| │ Studio Code Extension │
`---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? What type of extension do you want to create? (Use arrow keys)
> New Extension (TypeScript)
New Extension (JavaScript)
New Color Theme
New Language Support
New Code Snippets
New Keymap
New Extension Pack
New Language Pack (Localization)
New Web Extension (TypeScript)
New Notebook Renderer (TypeScript)
选择不同类型的扩展,但在我们的例子中,我们将使用某些选项
? What type of extension do you want to create? New Extension (TypeScript)
? Whats the name of your extension? HelloWorld
? Whats the identifier of your extension? helloworld
? Whats the description of your extension? LEAVE BLANK
? Initialize a git repository? Yes
? Bundle the source code with webpack? No
? Which package manager to use? npm
? Do you want to open the new folder with Visual Studio Code? Open with `code`
在编辑器中,打开src/extension.ts
并按F5
。这将在新的扩展开发主机窗口中编译并运行扩展。
从新窗口中的Hello World
命令面板运行命令Ctrl + Shift + P
输出将产生 VS Code 信息消息(默认):Hello World
你可以通过改变里面的东西来玩src/extension.ts
:
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "helloworld" is now active!');
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
let disposable = vscode.commands.registerCommand('helloworld.helloWorld', () => {
// The code you place here will be executed every time your command is executed
// Display a message box to the user
vscode.window.showInformationMessage('Hello World from Helloworld!');
});
context.subscriptions.push(disposable);
}
// This method is called when your extension is deactivated
export function deactivate() {}
该文件是您的扩展的基础。它包含 2 个重要的方法:activate和deactivate。导入的vscode.command模块注册命令和上下文参数共同订阅它们。
内package.json
{
...,
"activationEvents": [],
"contributes": {
"commands": [
{
"command": "helloworld.helloWorld",
"title": "Hello World"
}
]
},
}
Contributes.command:帮助在命令面板中显示带有标题的命令,还包含视图等。
激活事件:在特定条件下自动触发已注册的命令
为了更清楚地了解,您可以访问您的第一个 VS Code 扩展
但是,本文不仅仅涉及任何正常的扩展。对于 UI 部分,我们将通过 VS Code使用WebView 。
用于 UI 的 Webview API
Webview 允许扩展在 Visual Studio Code 中创建完全可自定义的视图。要快速实施,请按照以下步骤操作:使用以下代码
覆盖文件:src/extension.ts
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "Webview" is up and running now');
let webview = vscode.commands.registerCommand('helloworld.webview', () => {
let panel = vscode.window.createWebviewPanel("webview", "Web View", {
viewColumn: vscode.ViewColumn.One,
})
// will set the html here
panel.webview.html = `<h1>This is Heading 1</h1>
<h2>This is Heading 2</h2>
<h3>This is Heading 3</h3>
<h4>This is Heading 4</h4>
<h5>This is Heading 5</h5>`
});
});
context.subscriptions.push(webview);
}
export function deactivate() { }
需要注意的要点:
- 为了借助命令创建 Webview 面板
helloworld.webview
,我们需要使用它的回调来注册它。panel
用于将 html 设置到 webview 中。 - 在回调中,
vscode.window.createWebviewPanel
调用方法,该方法需要 4 个参数,,viewType
(title
webview 面板的标题),showOption
(哪个列和焦点),options
(重要的是,因为它处理安全性,如脚本编写和面板资源的可访问性)并且它回报vscode.WebviewPanel
- 重要步骤:如果您注册了新命令,请始终记住将其添加到
package.json
下contributes
。commands
{
...,
"contributes": {
"commands": [
{
"command": "helloworld.webview",
"title": "Web View"
}
]
},
}
然后,使用 运行扩展F5
,最终会打开另一个 vscode 窗口Extension Development
。然后按,在命令面板中Ctrl + Shift + P
输入 on (或您在 package.json 中提到的命令标题)。Web View
出现的窗口必须如下所示
设计用户界面
样式与通常使用 css 的网页相同,但有一个问题,如果您在外部编写 css,则需要首先允许该资源。
默认情况下,扩展位置和工作区中的所有本地资源都是可访问的。createWebviewPanel
要控制它们,只需通过提供第四个参数来更改代码即可localResourceRoots
。
// while creating panel allow the path you want to add
// in my case adding media as rootDir to localResources
let panel = vscode.window.createWebviewPanel("webview", "Web View", {
viewColumn: vscode.ViewColumn.One
},{ localResourceRoots: [vscode.Uri.joinPath(context.extensionUri, "media")]
})
下一步是media
在扩展文件夹内的根目录中创建一个名为的文件夹。
在该文件夹中,您可以放置所有样式文件,例如图像、svg、css 文件等。
vscode.css
在媒体文件夹中创建一个文件(您可以命名任何名称)。添加以下内容
:root {
--container-paddding: 20px;
--input-padding-vertical: 6px;
--input-padding-horizontal: 4px;
--input-margin-vertical: 4px;
--input-margin-horizontal: 0;
}
html {
box-sizing: border-box;
font-size: 13px;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body,
h1,
h2,
h3,
h4,
h5,
h6,
p,
ol,
ul {
margin: 0;
padding: 0;
font-weight: normal;
}
img {
max-width: 100%;
height: auto;
}
body {
padding: 0 var(--container-paddding);
color: var(--vscode-foreground);
font-size: var(--vscode-font-size);
font-weight: var(--vscode-font-weight);
font-family: var(--vscode-font-family);
background-color: var(--vscode-editor-background);
}
ol,
ul {
padding-left: var(--container-paddding);
}
body > *,
form > * {
margin-block-start: var(--input-margin-vertical);
margin-block-end: var(--input-margin-vertical);
}
*:focus {
outline-color: var(--vscode-focusBorder) !important;
}
a {
color: var(--vscode-textLink-foreground);
}
a:hover,
a:active {
color: var(--vscode-textLink-activeForeground);
}
code {
font-size: var(--vscode-editor-font-size);
font-family: var(--vscode-editor-font-family);
}
button {
border: none;
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
width: 100%;
text-align: center;
outline: 1px solid transparent;
outline-offset: 2px !important;
color: var(--vscode-button-foreground);
background: var(--vscode-button-background);
}
button:hover {
cursor: pointer;
background: var(--vscode-button-hoverBackground);
}
button:focus {
outline-color: var(--vscode-focusBorder);
}
button.secondary {
color: var(--vscode-button-secondaryForeground);
background: var(--vscode-button-secondaryBackground);
}
button.secondary:hover {
background: var(--vscode-button-secondaryHoverBackground);
}
input:not([type="checkbox"]),
textarea {
display: block;
width: 100%;
border: none;
font-family: var(--vscode-font-family);
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
color: var(--vscode-input-foreground);
outline-color: var(--vscode-input-border);
background-color: var(--vscode-input-background);
}
input::placeholder,
textarea::placeholder {
color: var(--vscode-input-placeholderForeground);
}
.container {
display: flex;
}
.form {
display: flex;
flex-direction: column;
flex: 1;
padding: 10px;
gap: 10px;
}
上面的样式将帮助您将 html 元素的默认样式属性重置为看起来像 vscode 的本机样式。上面提到的变量是由vscode直接提供的。
您还可以添加您选择的任何图像,只需将图像文件放入媒体文件夹中即可。
要应用 css 样式表和图像,只需添加此行并应用于 html
const cssStyle = panel.webview.asWebviewUri(vscode.Uri.joinPath(context.extensionUri, "media", "vscode.css"))
const imgSrc = panel.webview.asWebviewUri(vscode.Uri.joinPath(context.extensionUri, "media", "vim.svg"))
panel.webview.html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="${cssStyle}" />
</head>
<body>
<div class="container">
<img src="${imgSrc}" width="200" />
<div class="form">
<code>Title</code>
<input />
<code>Code</code>
<textarea></textarea>
<button>Submit</button>
</div>
</div>
</body>
</html>`
快速提示:要查看 html 中的更改,您需要重新加载整个扩展,Ctrl + R
以快速重新加载,无需每次都重新启动Ctrl + F5
预期输出:
脚本编写
您还可以使用 javascript 更新扩展内的 DOM。但需要先启用它。
let panel = vscode.window.createWebviewPanel("webview", "Web View", {
viewColumn: vscode.ViewColumn.One
},{
enableScripts: true
})
const scriptPath= panel.webview.asWebviewUri(vscode.Uri.joinPath(context.extensionUri, "media", "script.js"))
panel.webview.html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="${scripts}"></script>
</head>
<body>
<h1>Count:</h1>
<p id="count">0</p>
<button onclick="changeHeading()">Add</button>
</body>
</html>`
现在,在文件夹script.js
内创建文件media
,并添加以下行。
//script.js
function changeHeading() {
document.getElementById("count").textContent = +document.getElementById("count").textContent + 1
}
运行扩展后的预期输出动图
有趣的事实:您无需重新加载即可查看脚本部分的更改,只需关闭并重新打开 Web 视图即可。
实施 React、TypeScript、Tailwind
在了解了有关扩展和webviews的大量知识之后,是时候了解框架了,因为显而易见的原因是它们在使用不同的库时使事情变得更容易。
从 React 开始,您可以选择您选择的任何框架。
Step 1
初始化扩展yo code
yo code
? What type of extension do you want to create? New Extension (TypeScript)
? Whats the name of your extension? react-ext
? Whats the identifier of your extension? react-ext
? Whats the description of your extension? LEAVE BLANK
? Initialize a git repository? Yes
? Bundle the source code with webpack? No
? Which package manager to use? npm
? Do you want to open the new folder with Visual Studio Code? Open with `code`
Step 2
在根目录中使用typescript创建一个React应用程序。
npx create-react-app web --template typescript
cd web
Step 3
在react app目录中web
,设置tailwindcss
npm i -D tailwindcss postcss
npx tailwindcss init
编辑tailwind.config.js
//tailwind.config.js
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
}
编辑web/src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
@apply p-0;
}
Step 4
在 React 目录中,创建名为的文件.postcssrc
//.postcssrc
{
plugins: {
tailwindcss: { },
},
}
Step 5
编辑反应应用程序web/src/App.tsx
function App() {
return (
<div className="bg-gradient-to-r from-blue-600 to-purple-500 p-10">
<p className="text-white/80 text-xl font-semibold">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Ea, explicabo
doloremque deserunt, voluptates, fugiat dolorem consectetur odio autem
quas ipsa veniam ducimus necessitatibus exercitationem numquam assumenda
natus beatae sed velit!
</p>
</div>
);
}
export default App;
Step 6
安装Parcel,最轻量级的打包器(老实说,在尝试了 webpack 、 babel 和 rollup 之后,我觉得浪费时间)
Parcel
作为开发依赖项安装在React根目录中web
npm i -D parcel
在 React 应用程序内部,编辑package.json
//web/package.json
{
...,
"source": "src/index.tsx",
"scripts": {
"start": "parcel", //overwrite
"build": "parcel build", //overwrite
"test": "react-scripts test",
"eject": "react-scripts eject"
},
}
运行包裹 (Parcelling)
npm start
#> web@0.1.0 start
#> parcel
#Server running at http://localhost:1234
每次您更改内部或与likesrc
相关的内容时,它都会重新运行快速构建并将其存储在React 应用程序目录内的文件夹中,如和。src/index.tsx
index.css
dist
index.js
index.css
Step 7
现在进入扩展集成部分,编辑src/extension.ts
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
let webview = vscode.commands.registerCommand('react-ext.namasteworld', () => {
let panel = vscode.window.createWebviewPanel("webview", "React", vscode.ViewColumn.One, {
enableScripts: true
})
// web is for my react root directory, rename for yours
let scriptSrc = panel.webview.asWebviewUri(vscode.Uri.joinPath(context.extensionUri, "web", "dist", "index.js"))
let cssSrc = panel.webview.asWebviewUri(vscode.Uri.joinPath(context.extensionUri, "web", "dist", "index.css"))
panel.webview.html = `<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="${cssSrc}" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="${scriptSrc}"></script>
</body>
</html>
`
});
context.subscriptions.push(webview);
}
export function deactivate() { }
最重要的过程!
不要忘记在 package.json 中手动写入所有注册的命令,这将导致命令面板中缺少 UI 选项Ctrl+Shift+P
为此,请转到扩展根目录的 package.json
{
...,
"contributes": {
"commands": [
{
"command": "react-ext.namasteworld",
"title": "React Web View"
}
]
},
}
Final Step
现在,到了关键时刻
- 只需按,就会打开
Ctrl F5
另一个扩展开发。 - 在另一个测试 vscode 编辑器Extension Development上,按按打开命令面板
Ctrl+Shift+P
- 搜索您注册的命令,您在 中给出的名称
package.json
,在我的例子中是React Web View
并且必须弹出类似的窗口,如下所示
预期步骤:
有趣的事实:在 React 应用程序中进行更改后,您不需要重新运行,或者App.tsx
重新打开窗口,如下所示
奖励:VS Code UI 工具包 (React)
使用框架而不是原始 html 的优点,您可以使用 shadcn ui、framermotion 等 UI 库
一个这样有用的例子是我们自己开发的Webview UI Toolkit
这是一个令人惊叹的 ui 库,它使您制作的扩展感觉就像它们的原生扩展一样。
要实现你只需要安装vscode/webview-ui-toolkit
在你的反应应用程序中
npm install --save @vscode/webview-ui-toolkit
编辑App.tsx
import {
VSCodeButton,
VSCodeDataGrid,
VSCodeDataGridRow,
VSCodeDataGridCell,
VSCodeTextField,
VSCodeProgressRing,
} from "@vscode/webview-ui-toolkit/react";
function App() {
const rowData = [
{
cell1: "Cell Data",
cell2: "Cell Data",
cell3: "Cell Data",
cell4: "Cell Data",
},
{
cell1: "Cell Data",
cell2: "Cell Data",
cell3: "Cell Data",
cell4: "Cell Data",
},
{
cell1: "Cell Data",
cell2: "Cell Data",
cell3: "Cell Data",
cell4: "Cell Data",
},
];
return (
<div className="grid gap-3 p-2 place-items-start">
<VSCodeDataGrid>
<VSCodeDataGridRow row-type="header">
<VSCodeDataGridCell cell-type="columnheader" grid-column="1">
A Custom Header Title
</VSCodeDataGridCell>
<VSCodeDataGridCell cell-type="columnheader" grid-column="2">
Another Custom Title
</VSCodeDataGridCell>
<VSCodeDataGridCell cell-type="columnheader" grid-column="3">
Title Is Custom
</VSCodeDataGridCell>
<VSCodeDataGridCell cell-type="columnheader" grid-column="4">
Custom Title
</VSCodeDataGridCell>
</VSCodeDataGridRow>
{rowData.map((row) => (
<VSCodeDataGridRow>
<VSCodeDataGridCell grid-column="1">{row.cell1}</VSCodeDataGridCell>
<VSCodeDataGridCell grid-column="2">{row.cell2}</VSCodeDataGridCell>
<VSCodeDataGridCell grid-column="3">{row.cell3}</VSCodeDataGridCell>
<VSCodeDataGridCell grid-column="4">{row.cell4}</VSCodeDataGridCell>
</VSCodeDataGridRow>
))}
</VSCodeDataGrid>
<span className="flex gap-3">
<VSCodeProgressRing />
<VSCodeTextField />
<VSCodeButton>Add</VSCodeButton>
<VSCodeButton appearance="secondary">Remove</VSCodeButton>
</span>
</div>
);
}
export default App;
这个库最好的部分是,它适应 vscode 中的每个可用主题,使用它们的 css 变量(我猜),这是惊人的。
这是一个示例动图
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=5vbhp91f157x
请登录后查看评论内容