VS Code 扩展开发如何保持用户视觉体验一致

简介: 本文介绍如何在 VS Code 插件的 webview 中加载本地的资源文件,并如何使用 VS Code 自身的 UI 来实现用户视觉体验的一致。

背景

最近想做一个 VS Code 的插件用来简便我使用 VS Code 来编辑 Markdown 博客的体验,在设计插件的过程中,因为需要在 webview 界面中使用到下拉框,想到为了节省插件大小,并考虑到用户体验一致性,故需要使用 VS Code 自身的 UI 库。

寻找蛛丝马迹:获取安装目录

因为我不清楚到底要如何去做,就先自己探索。先打开了 VS Code 的开发人员工具进行元素审查,看到是 workbench.desktop.main.css 这个文件。

审查html

<link rel="stylesheet" type="text/css" data-name="vs/workbench/workbench.desktop.main" href="vscode-file://vscode-app/d:/Program%20Files/Microsoft%20VS%20Code/resources/app/out/vs/workbench/workbench.desktop.main.css">

根据以上信息我们可以得知,其实际目录需要特殊的魔法去获取,因为引用的路径是安装目录的位置,不同电脑的肯定是不一样的。

这里我们就前往 VS Code 的仓库去扒拉源代码,最后虽然根据 vs/workbench/workbench.desktop.main 找到了一些线索,但是不堪大用啊,还是需要找到安装目录才行。几番折腾发现源码里获取软件版本信息 product.json 的方法,原来里面有环境变量啊。

const product = JSON.parse(fs.readFileSync(path.join(env.appRoot, 'product.json'), { encoding: 'utf-8' }));

那么,若在插件中要想获取到安装目录,直接使用下面的方法就好了:

const vscodeInstallPath = vscode.env.appRoot;

插件中获取

一波三折,并不顺利

首先在插件中,我们获取 html 内容后替换占位符信息如下:

const appRoot = vscode.Uri.file(vscode.env.appRoot);
this.view.webview.html = html.replace(/\[insert-vscode-root\]/g,`${appRoot}`);

通过替换 webview 页面的引用信息,实现动态的 workbench.desktop.main.css 资源引用后,不出意外的出了意外了:

出错

虽然看起来引用的路径是没有什么问题了,但是结果却令人糟心啊:

Not allowed to load local resource

期间我尝试了 vscode-file://vscode-app/ 协议直接拼接 appRootasWebviewUri 但是并没有成功获取到,都是网络错误。

asWebviewUri 看起来似乎有些靠谱,观察开发人员工具中的网络请求似乎很多都是这样类似的连接:

https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/sangsq/AppData/Local/Programs/Microsoft%20VS%20Code/resources/app/out/vs/workbench/workbench.desktop.main.css

不过这个 net::ERR_ABORTED 401 却是让人高兴不起来,貌似权限问题。此时凌晨已至,夜寒露重,故搜索了一遍 Stackoverflow 后,便提了一个问题关机睡觉。

继续探索

在没有获得到答案后,还是要靠自己。认真看看官方文档,在扩展指南的加载本地内容中得到了一些答案。

出于安全原因,Webview 运行在隔离的环境中,无法直接访问本地资源。想从扩展加载图片、样式表或其他资源,或者从用户当前的工作区加载任何内容,必须使用 Webview.asWebviewUri 来转换为一个特殊的 URI 来使用。

前面已经提到我用过了 Webview.asWebviewUri 但是还有一些其他限制,默认情况下 Webview 只能访问以下位置的资源:

  • 扩展程序的安装目录
  • 用户当前的活动工作区

使用 WebviewOptions.localResourceRoots 可以允许访问其他本地资源。

createWebviewPanel 方法的第4个参数 webviewOptions.localResourceRoots 是一个只读数组,默认情况就是之前提的扩展程序的安装目录和用户当前的活动工作区。当然你也可以设置成空数组,这样就禁止访问任何本地资源。

这样在创建时稍作修改就可以了。

this.view = vscode.window.createWebviewPanel(
    "blogPreview",
    "Markdown Blog Preview",
    vscode.ViewColumn.Two,
    {
        enableScripts: true,
        localResourceRoots: [
            vscode.Uri.file(path.join(context.extensionPath, "html")),
            vscode.Uri.file(vscode.env.appRoot)
        ]
    }
);

在 html 内容中替换指定的字符串:

<link rel="stylesheet" type="text/css" href="[insert-vscode-css]">
const cssfile = vscode.Uri.file(path.join(vscode.env.appRoot,"out/vs/workbench/workbench.desktop.main.css"));
const cssurl = this.view.webview.asWebviewUri(cssfile);
this.view.webview.html = html.replace(/\[insert-vscode-css\]/g,`${cssurl}`);

最后成果

在 workbench 目录中还存在有其他可用资源,这里仅对 select 的效果做个演示。

未使用 VS Code 的 UI 时:

未使用

使用 VS Code 的 UI 时:

使用

另外在 Webview 的 html 显示中会被加入当前的样式和主题信息,需要自行进行适配调整。

<html lang="zh-CN" style="--vscode-font-family:………略,太多了………">
<body role="document" class="vscode-dark" data-vscode-theme-kind="vscode-dark" data-vscode-theme-name="Dark+ (default dark)" data-vscode-theme-id="Default Dark+">
相关文章
|
11天前
|
开发框架 .NET C#
VSCode开发.net项目时调试无效
【9月更文挑战第22天】在使用 VSCode 开发 .NET 项目时遇到调试问题,可从项目配置、调试配置、调试器安装、运行环境、日志和错误信息等方面排查。确认项目类型及文件配置,检查 `launch.json` 文件及配置项,确保调试器扩展已安装并启用,验证 .NET 运行时版本和环境变量,查看 VSCode 输出窗口和项目日志文件,检查权限及代码错误。若问题仍未解决,可查阅官方文档或社区论坛。
|
2月前
|
缓存 C++ 索引
STM32 VS Code 扩展用户指南(三)
STM32 VS Code 扩展用户指南
51 3
|
2月前
|
C++
STM32 VS Code 扩展用户指南(二)
STM32 VS Code 扩展用户指南
54 3
|
2月前
|
JSON 编解码 C++
STM32 VS Code 扩展用户指南(一)
STM32 VS Code 扩展用户指南
49 2
|
4月前
|
C# 图形学 C++
使用vscode开发C#+unity没有代码提示问题
使用vscode开发C#+unity没有代码提示问题
54 0
使用vscode开发C#+unity没有代码提示问题
|
3月前
|
JSON 小程序 数据格式
uni-app 使用vscode开发uni-app
uni-app 使用vscode开发uni-app
170 0
|
3月前
|
JSON 数据格式
3. 使用 VsCode 开发 uni-app 项目需要使用到的插件
3. 使用 VsCode 开发 uni-app 项目需要使用到的插件
79 0
|
5月前
|
API 开发工具 C++
【专栏:工具与技巧篇】使用代码编辑器(VS Code/Sublime Text)提升开发效率
【4月更文挑战第30天】在VS Code与Sublime Text两大流行代码编辑器中,开发者可借助其高效特性提升编程效率。VS Code拥有丰富的插件生态、内置Git集成、强大的调试工具、智能提示和多文件导航功能。Sublime Text则以其轻量级、快速响应、多光标编辑及自定义构建系统见长。学习编辑器的键盘快捷键、自定义配置、使用内置终端以及键绑定和宏,将助开发者进一步提高开发效率。选择适合自己的编辑器并不断适应新技术是提升开发工作流的关键。
285 1
下一篇
无影云桌面