在上一篇文章 - 最简单的一个VSCode插件中,我们学习了如何创建一个简单的VSCode插件,实现了一个基本的图片调整大小功能。然而,那个插件的用户界面比较简单,只能通过输入框来设置图片宽度。在这篇文章中,我们将学习如何使用React、Tailwind CSS、Shadcn和Vite来创建一个更复杂、更美观的Webview界面,提供更丰富的图片编辑功能。
1. 环境准备
1.1 回顾上一篇项目
我们将在上一篇创建的letsdoit-image插件基础上进行扩展。如果你还没有完成上一篇的内容,请先按照那篇文章创建一个基本的VSCode插件项目。
1.2 首先创建一个最简单的webview
在package.json中声明一个新的命令:
1 | "commands": [ |
然后在src/extension.ts中注册并添加命令的实现代码,现在我们只是简单的显示文本Edit Image:
1 | const editImageDisposable = vscode.commands.registerCommand('letsdoit-image.editImage', async () => { |
注意:在上面的代码中,我们使用了
enableScripts: true, 这里必须设为true,否则后面我们的React应用将无法运行。另外,我们还设置了retainContextWhenHidden: true,这意味着当Webview面板被隐藏时,它的上下文将被保留,而不是被销毁。这对于我们的插件来说是非常重要的,因为我们希望用户能够在编辑图片后,能够继续在VSCode中进行其他操作,比如编辑其他的文件。
我们按F5运行插件,在新打开的VSCode窗口中按Ctrl+Shift+P,输入图片快修,即可打开我们的插件。顺利的话,我们应该看到下面的界面:
1.3 然后创建一个React项目来实现webview的内容
首先,我们需要在插件项目中创建一个用于Webview的React应用。我们将使用Vite来创建一个React项目,因为它提供了快速的开发体验和优秀的构建性能。
在插件项目根目录下执行以下命令:
1 | # 创建一个React + TypeScript项目 |
1.4 配置Tailwind CSS
- 修改
webview/tsconfig.json中配置compilerOptions如下:
1 | { |
- 同样的,还要修改
webview/tsconfig.app.json中配置compilerOptions如下:
1 | { |
- 在
webview/src/index.css中引入Tailwindcss, 删除原来内容。
1 | @import 'tailwindcss'; |
- 最后,我们修改下vite的配置文件
vite.config.ts,使其支持tailwindcss:
1 | // other code |
2. 开发React Webview界面
2.1 实现图片编辑功能
在webview/src/App.tsx中实现图片编辑功能,由于内容比较多,这里就不贴代码了,如果有兴趣可以查看完整代码。
2.2 配置Vite构建
我们需要修改vite.config.ts文件,将构建输出目录改为../out/,并将入口js文件名改为assets/index.js,因为默认生成的js文件名会带上hash值,而我们需要在src/extension.ts中引用这个文件,所以简单起见这里需要指定为固定文件名。
1 | export default defineConfig({ |
3. 将React应用集成到webview中
3.1 调整webview显示内容
修改src/extension.ts文件,添加Webview相关代码:
1 | const jsUri = panel.webview.asWebviewUri(vscode.Uri.joinPath(context.extensionUri, 'out', 'assets', 'index.js')); |
注意:上面代码中,我们将React应用的入口js文件和css文件都加载到了webview中,这是因为我们需要在webview中运行React应用。这是将React应用的内容嵌入到webview的关键步骤。另外,我们注意到
panel.webview.asWebviewUri方法用于将插件项目中的文件路径转换为webview可以访问的URI,这是因为webview访问插件本地资源有特殊的安全控制,必须转换成WebviewUri才能访问。
3.2 处理下载文件的问题
由于webview运行在一个独立的环境中,直接使用浏览器的下载功能可能会受到限制。为了解决这个问题,我们可以通过VSCode的消息传递机制,将下载请求发送回扩展主进程,由主进程来处理文件保存。
首先在下载图片的逻辑中,我们发送一个消息给扩展主进程,请求保存图片:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28// 在VSCode插件环境中,使用postMessage与插件通信
if (vscode) {
// 从data URL中提取base64数据和图片格式
const mimeType = imageToDownload.match(/^data:(image\/[a-z]+);base64,/)?.[1] || 'image/png';
const base64Data = imageToDownload.replace(/^data:image\/[a-z]+;base64,/, '');
// 根据MIME类型确定文件扩展名
let extension = 'png';
if (mimeType.includes('jpeg') || mimeType.includes('jpg')) {
extension = 'jpg';
} else if (mimeType.includes('png')) {
extension = 'png';
} else if (mimeType.includes('gif')) {
extension = 'gif';
} else if (mimeType.includes('webp')) {
extension = 'webp';
}
// 发送消息给VSCode插件,请求保存文件
vscode.postMessage({
command: 'saveImage',
data: base64Data,
fileName: `edited-image.${extension}`
});
} else {
// 在普通浏览器环境中使用原有下载方式
}然后在
extension.ts中添加消息监听,处理保存图片请求:
1 | // 处理来自webview的消息 |
4. 测试插件
至此,我们已经完成了代码的编写,可以开始测试了。
我们先在webview目录下运行npm run build,确保React应用的代码已经构建完成。
- 在VSCode中打开插件项目
- 按
F5或点击”运行 > 启动调试” - 在新打开的VSCode窗口中,
Ctrl+Shift+P打开命令面板,输入”图片快修” - 在打开的Webview中编辑图片
- 点击”下载”按钮保存编辑后的图片
5. 打包和发布
一切顺利,我们该打包了。
5.1 添加构建脚本
在插件项目的package.json中添加构建脚本:
1 | { |
如果我们还没有安装vsce,可以使用以下命令安装:
1 | npm install -g vsce |
5.2 打包插件
运行以下命令打包插件:
1 | npm run package |
成功后,会在项目根目录下生成一个.vsix文件,这就是我们的插件安装包。
5.3 发布插件
按照上一篇文章中的步骤,将插件发布到VSCode Marketplace。
6. 总结
在这篇文章中,我们学习了如何使用React、Tailwind CSS、Shadcn和Vite来创建一个复杂的Webview界面,并将其集成到VSCode插件中。这个插件我们已经发布到VSCode Marketplace,你可以在插件市场搜索”图片快修”来安装它。
但是现在还有个问题,就是我们打的包有10多MB,这对于一个简单的插件来说是比较大的。后面一篇文章我们会介绍如何优化插件的大小,正常情况下,我们这个插件应该在100K以内。
希望这篇文章能帮助你进一步了解VSCode插件开发!如果你有任何问题或建议,欢迎在评论区留言讨论。