VSCode For Web 深入浅出 -- 插件加载机制

news2024/12/25 9:29:06

最近我在浏览 VSCode for web 的 repo,在最近更新的一些 commit 中发现了一个新的 VSCode 插件特性支持,名为 webOpener,它的作用是什么呢?又是如何影响插件加载的呢?在这一篇中我们结合 VSCode For Web 的插件加载机制来详细分析一下。


VSCode for web 的插件加载机制

我们知道,由于 VSCode for web 运行在浏览器上,因此,它的插件加载机制与 VSCode for desktop 有所不同。

在 VSCode for desktop 中,插件是以 vsix 包的形式存在的,因此,VSCode for desktop 可以直接通过 vsix 包的形式加载插件。而在 VSCode for web 中,由于浏览器的安全机制,不能直接加载 vsix 包。

因此,VSCode for web 采用了一种特殊的插件加载机制。发布 VSCode for web 插件时,发布系统会直接将项目编译,并发布到 CDN 节点上。当用户加载插件时,通过向该目标 url 发送请求,拉取远端(也可以是本地)的 extension.js 文件。并利用 web worker 加载机制,为每个插件分配独立线程加载与执行。

在生产环境中,对每个进入 VSCode 插件商店的插件,VSCode for web 会将支持 web 环境的插件的 package.jsonextension.js 等文件打包成一个 zip 包,然后根据 publisher 分配合适的二级域名,通过 CDN 分发。

以我在使用的One Dark Pro主题为例:

20230508145433

而在调试模式中,我们可以通过 Install extension from location...命令,指定编译后插件的 url,从而加载插件。

20230508143115

我们使用本地服务器,指定一个已编译好的 VSCode web extension,并填入本地服务器地址 (https://localhost:5000),并刷新页面,那么从 Chrome 的 Network 中可以看到 VSCode 向目标位置请求了package.jsonextension.js,并看到插件已经被成功加载了。

20230508144906

通过这样的方式,VSCode for web 在每次页面打开后,完成了对用户自定义的插件管理与加载。并由于web worker的特性,每个插件的执行环境都是独立且相互隔离的。

通过特殊 url 路由的方式的插件加载机制

VSCode for web 最突出的特点是它是运行在浏览器上的,因此,我们可以利用 url,来实现一些奇妙的新特性。例如,通过特殊的 url 路由,免安装地加载插件。

目前,vscode.dev 可以使用这样的方式加载插件:

https://vscode.dev/+publisher.name

例如,在浏览器中输入 https://vscode.dev/+ms-vscode.onedrive-browser 将加载 OneDrive 浏览器扩展。

当然,我们也可以使用同样的方式加载本地编译的插件。由于 vscode.dev 强制要求 secure context ,因此,我们需要在本地启动一个 https 的服务器,并对 url 进行 base64 编码,才能正常访问。

访问https://vscode.dev/+aHR0cHM6Ly9sb2NhbGhvc3Q6MzAwMA==即可。(后面那一段为"https://localhost:3000") 的 base64 编码)

webOpener 特性介绍

有开发过 VSCode for desktop 的插件的同学应该知道,vscode 插件的所有能力都是在 package.json 中声明的,这也是为什么 VSCode 除了需要加载入口的 extension.js 外,还一定要加载插件的 package.json 的原因。

在插件 package.jsoncontributes 字段中,我们可以声明插件的各种能力,例如,命令、菜单、快捷键、主题、语言、调试器等等。

对于 vscode for web 版本的插件来说,我们还可以声明 webOpener 能力,其所有属性都是可选的。声明如下:

{
  "name": "onedrive-browser",
  "contributes": {
    "webOpener": {
      "scheme": "onedrive",
      "import": "webOpener.js",
      "runCommands": [{ "command": "hello-world", "args": ["$url"] }]
    }
    ...
  }
}

webOpener.scheme

默认情况下,vscode.dev/+publisher.name 路由将直接打开默认的 VSCode 示例工作区。但是,如果提供了 scheme path,则 VSCode 将根据路由参数打开一个以该协议打开 url 中后续 path 指向的文件夹,格式如下:

# 当 scheme 设置为 onedrive
https://vscode.dev/+publisher.name/remoteAuthority/path/segments/...

例如,当插件 webOpener 的 scheme 设置为 onedrive 时,访问 https://vscode.dev/+ms-vscode.onedrive-browser/myPersonalDrive/cool/folder ,此时访问 url 将重定向为 onedrive:///myPersonalDrive/cool/folder

若此协议不在 VSCode 的内置协议中,我们可以在插件中通过 vscode.workspace.registerFileSystemProvider 这个 API 注册自定义的 FileSystemProvider,从而实现对自定义协议的 FileSystem 支持。

本质上,它打开的方式与 VSCode for web 的 vscode.open 命令也是一致的。

webOpener.runCommands

当 VSCode 的主 workbench 加载完毕后,会触发 webOpeneronDidCreateWorkbench 的钩子,并执行此处声明的命令集。

这将传入一个命令数组,例如:[{ "command": "test-extension.hello-world", "args": ["$url"] }],此时将可以执行自定义插件 test-extension 的相关命令。

其中,$url 指代当前页面 url。如果插件的初始化依赖来自 url 的 query/path 等等信息,这将很有用。

webOpener.import

这里定义了 webOpener 加载的入口点。它是一个相对于插件 package.json 的 ES Module 路径,例如:webOpener.js

它与 extension.js 一样,默认导出一个 doRoute 函数,该函数将获取 route 与 workbench 等信息(workbench 这个实例中提供了当前 vscode for web 的命令、日志、环境、window、workspace 等多种能力支持)。由于 webOpener.js 运行在主线程中,因此它能做到的事情要比处于 web worker 下的 vscode for web 插件更多。

举一个例子,这是一个简单的 webOpener 贡献 onedrive-browser:

export default function doRoute(route) {
  // If we're not already opening a OneDrive, show the picker immediately
  // when the user hits `vscode.dev/+ms-vscode.onedrive-browser`.
  if (route.workspace.folderUri?.scheme !== 'onedrive') {
    route.onDidCreateWorkbench.runCommands.push({
      command: 'onedrive-browser.openOneDrive',
      args: [],
    });
  }
}

它将在 workbench 加载完毕后,判断当前的 workspace 是否为 onedrive,如果不是,则执行 onedrive-browser.openOneDrive 命令,从而打开 onedrive 文件夹。

webOpener 与插件的通信机制

在了解了 webOpener 的基本特性之后,我们来看看该如何利用这些特性,与我们的 web 插件进行通信,从而扩展插件能力。

我们可以看出,由于 webOpener 加载在主线程,且 doRoute 方法的执行时机在主线程 workbench 加载完毕之后,在请求远端插件并执行之前。因此,我们可以有两种方式来传递信息,与处于 web worker 下,与宿主隔离的插件进行通信。

第一种即为在 runCommands 中介绍的,通过执行 command 并传递 url 的方式传递初始化信息。该方式也是 webOpener 与插件通信的常用方式之一,用于为初始化插件时提供部分依赖参数。

第二种则是通过 doRoute 方法,捕获此时的请求信息,并根据请求信息的不同对插件能力进行不同的变更,但本质上还是通过 command 的方式给插件发送 args 来实现的。

我在当前最新版本的 vscode-dev 代码库中(1.79.0),并未发现直接通过 webOpener 暴露类似 postMessage 的与插件通信的方法,因此到目前为止,我们只能通过给插件的 command 方式触发 trigger 与传入参数这一种方式来实现与插件的通信。这导致了在 web 下插件的能力其实相当受限。

总结

本篇文章解析了在 VSCode for web 中的插件加载机制,以及如何通过 webOpener 特性来扩展插件的能力。

我们可以看出,在现阶段的 VSCode for web 中,插件的加载机制也仅仅只是做到了可用状态。由于 web worker 天然的与主线程隔离的特性,desktop 的很多好用的功能性插件(即除了 theme/key-binding 这种不需要执行逻辑的插件之外)在 web 端的支持还是会遇到很多问题,并不能无缝迁移。这点也是我在尝试开发 VSCode for web 插件时最大的痛点。

不过,随着 VSCode for web 项目仍在进行高频的开发与完善,希望未来的 VSCode for web 能在插件开发与使用上尽可能对齐甚至兼容 desktop 的体验。

参考资料

  • VSCode dev Repository (目前是私有仓库,需要向 Microsoft 申请权限,未来功能完善后或将开放)
  • VSCode for the Web Introduction

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/503152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大项目准备(2)

目录 中国十大最具发展潜力城市 docker是什么?能介绍一下吗? 中国十大最具发展潜力城市 按照人随产业走、产业决定城市兴衰、规模经济和交通成本等区位因素决定产业布局的基本逻辑,我们在《中国城市发展潜力排名:2022》研究报告…

uniapp和小程序如何分包,详细步骤手把手(图解)

一、小程序分包 每个使用分包小程序必定含有一个主包。所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分。 在小程序启动时,默认会下载主包并启动主包…

C++学习day--11 程序员必备工具--github

github 的重要性: 网络时代的程序员必备。 github 的作用: 1. 版本管理 2. 多人协作 3. 开源共享 常用方案: gitTortoiseGitgithub [Tortoise ,程序员常称其为小乌龟,小海龟 ] 安装配置步骤 1. 注册 h…

13 KVM虚拟机配置-配置虚拟设备(总线配置)

文章目录 13 KVM虚拟机配置-配置虚拟设备(总线配置)13.1 概述13.2 元素介绍13.3 配置示例 13 KVM虚拟机配置-配置虚拟设备(总线配置) 13.1 概述 总线是计算机各个部件之间进行信息通信的通道。外部设备需要挂载到对应的总线上&a…

MySQL调优系列(四)——执行计划

一、概述 sql语句是有具体的执行过程的,通过查看这个执行过程,可以针对性的优化某一步骤,以加快SQL语句的执行效率。 通过MySQL调优系列(一)——性能监控我们可以知道,有一个查询优化器,查询优…

HTTP第五讲——搭建HTTP实验环境

HTTP简介 HTTP 协议诞生于 30 年前,设计之初的目的是用来传输纯文本数据。但由于形式灵活,搭配URI、HTML 等技术能够把互联网上的资源都联系起来,构成一个复杂的超文本系统,让人们自由地获取信息,所以得到了迅猛发展。…

D. Petya and Array(树状数组 + 前缀和 + 逆序对的思想)

Problem - D - Codeforces Petya 有一个由 n 个整数组成的数组 a。他最近学习了部分和,现在他可以非常快地计算出数组中任何一段元素的和。这个段是一个非空的序列,相邻的元素排在数组中。 现在他想知道他的数组中元素和小于 t 的段的数量。请帮助 Pety…

鸿蒙Hi3861学习九-Huawei LiteOS(互斥锁)

一、简介 互斥锁又被称为互斥型信号量,是一种特殊的二值信号量,用于实现对共享资源的独占式处理。 任意时刻互斥锁的状态只有两种:开锁或闭锁。 当有任务占用公共资源时,互斥锁处于闭锁状态,这个任务获得该互斥锁的使用…

lua | 循环和函数的使用

目录 一、循环与流程控制 循环 流程控制 二、函数 函数 多返回值 可变参数 本文章为笔者学习分享 学习网站:Lua 基本语法 | 菜鸟教程 一、循环与流程控制 循环 lua语言提供了以下几种循环处理方式: 1.while 条件为true时,程序重复…

数据结构(六)—— 二叉树(7)构建二叉树

文章目录 如何使用递归构建二叉树1、创建一颗全新树(题1-5)2、在原有的树上新增东西(题6) 1 106 从 后序 与 中序 遍历序列构造二叉树2 105 从 前序 与 中序 遍历序列构造二叉树3 108 将有序数组转换为二叉搜索树(输入…

施耐德电气 × 牛客:HR如何助力业务数字化转型?

历经一百八十多年的发展,施耐德电气从一家钢铁企业,进入电力与控制领域,再到如今成为全球能源管理和自动化领域的数字化专家,业务覆盖100多个国家,拥有近13万员工。 其背后离不开HR强大后盾的支撑,下面将独…

Linux文件系统目录有什么用?

学习文件系统的意义在于文件系统有很多设计思路可以迁移到实际的工作场景中,比如: MySQL 的 binlog 和 Redis AOF 都像极了日志文件系统的设计;B Tree用于加速磁盘数据访问的设计,对于索引设计也有通用的意义。 特别是近年来分布…

【Java|golang】1010. 总持续时间可被 60 整除的歌曲

在歌曲列表中&#xff0c;第 i 首歌曲的持续时间为 time[i] 秒。 返回其总持续时间&#xff08;以秒为单位&#xff09;可被 60 整除的歌曲对的数量。形式上&#xff0c;我们希望下标数字 i 和 j 满足 i < j 且有 (time[i] time[j]) % 60 0。 示例 1&#xff1a; 输入&…

【LangChain】如何本地部署基于chatGPT的实时文档和表格数据的助手,在自己的数据上构建chatGPT?

【LangChain】如何本地部署基于chatGPT的实时文档和表格数据的助手&#xff0c;在自己的数据上构建chatGPT 1 相关技术 &#xff08;1&#xff09;LangChain 是一个用于自然语言处理的 Python 库&#xff0c;它的目标是尝试简化自然语言处理任务&#xff0c;提高处理效率和准…

渲染对电脑伤害大吗_如何减少渲染伤机?

虽然说摄影穷三代&#xff0c;但想要自己的本地配置跟上自己的创作速度&#xff0c;高昂的硬件配置支出也可以让自己穷一段时间。CG制作过程中&#xff0c;渲染是必不可少的一步&#xff0c;而且这一步也是很吃“机器”的&#xff0c;那很多人也会担心&#xff0c;如果经常用自…

如何构建产品帮助中心?

据研究表明超过50%的互联网用户&#xff0c;更愿意使用网站中的自助服务支持去解决产品使用中的问题。那么这个时候在线帮助中心&#xff08;即在线帮助页面&#xff09;&#xff0c;就满足了用户这个需求。 在线帮助中心是一个丰富的知识库&#xff0c;可以指导企业的潜在客户…

asp.net+sqlserver漫画绘本借阅管理系统

摘 要1 第1章 系统概述5 1.1 研究背景5 1.2 研究的意义5 1.3 主要研究内容5 第2章 系统开发环境7 2.1 ASP.NET概述7 2.2 动态网站技术介绍8 2.3 数据库技术8 第3章 需求分析9 3.1 需求分析9 3.1.1 功能需求9 3.2 可行性分析9 3.2.1 可行性分析9 3.2.2 技术可行性9 3.2.3 运行可…

OpenCV4 学习指导1 —— Mat:最基本的图像容器

Mat: CV基本的数据结构 1、认识数字图像2、CV的发展历程3、Mat的基本结构3.1、Mat—浅拷贝3.2、Mat—深拷贝 4、颜色的表示方法5、创建Mat对象方法集合5.1、Mat类的常用成员函数5.2、Mat类的成员函数举例 6、Mat的输出样式7、Point 数据存储结构8、参考资源 1、认识数字图像 我…

Yolov8改进---注意力机制:Polarized Self-Attention,效果秒杀CBAM、SE

1. Polarized Self-Attention 论文:https://export.arxiv.org/pdf/2107.00782.pdf Polarized self-attention是一种改进的自注意力机制,旨在提高自注意力模型的效率和准确性。传统的自注意力机制通常需要计算所有位置对所有位置的注意力,这会导致计算复杂度的增加和模型的训…

君子签:助力高校毕业、就业协议电子签,打通就业最后一公里

据介绍&#xff0c;2023届全国普通高校毕业生规模预计达1158万人&#xff0c;同比增加82万人。毕业季即将来临&#xff0c;全国各大高校毕业、就业材料签署压力大&#xff0c;盖章需求激增&#xff0c;如何快捷、高效地处理各类毕业、就业材料签署问题呢&#xff1f; 在教育部…