一. 关于VS Code插件
VS Code插件简介
vscode是微软出的一款轻量级代码编辑器,IDE只提供了基本功能和框架,有很多功能都是由插件丰富和扩展的。
VS Code插件功能
1.不受限的本地磁盘访问
2.自定义命令、快捷键、菜单
3.自定义跳转、自动补全、悬浮提示
4.自定义插件设置、自定义插件欢迎页
5.自定义WebView
6.自定义左侧功能面板
7.自定义颜色、图标主题
8.新增语言支持(代码高亮、语法解析、折叠、跳转、补全等)
9.Markdown增强
10.其他(比如状态栏修改、通知提示、编辑器控制、git源代码控制、任务定义、Language Server、Debug Adapter等等)
二 . 搭建VS Code项目
安装脚手架
- 确保已安装Node.js和Git
- 使用
npm install -g yo generator-code
命令安装Yeoman和VS Code Extension Generator
创建项目
yo code
// 项目语言
# ? What type of extension do you want to create? New Extension (TypeScript)
// 项目名称
# ? What's the name of your extension? HelloWorld
### Press <Enter> to choose default for all options below ###
// 项目标识符
# ? What's the identifier of your extension? helloworld
// 项目描述
# ? What's the description of your extension? LEAVE BLANK
// 是否初始化git仓库
# ? Initialize a git repository? Yes
// 是否需要webpack打包
# ? Bundle the source code with webpack? No
// 使用哪个包管理器
# ? Which package manager to use? npm
// 是否要使用Visual Studio代码打开新文件夹?
# ? Do you want to open the new folder with Visual Studio Code? Open with `code`
三 . 项目结构
扩展文件结构
**以JavaScript类型讲解一下项目架构**
├── .vscode // vscode调试配置
| ├── launch.json // 用于启动和调试扩展的配置
| └── tasks.json // 编译生成任务的配置
├── .gitignore // 发布忽略内容
├── CHANGELOG.md // 修改日志
├── README.md // 插件发布后,插件主页内容
├── package-lock.json
├── package.json // vscode从这里识别插件贡献点
├── src // 核心源码内容
| ├── extension.ts // 入口文件
| └── test //测试文件
├── jsconfig.json // 配置文件
├── vsc-extension-quickstart.md
└── webpack.config.js // wepack配置
核心内容讲解
- package.json
字段名称 | 含义 |
---|---|
name | 插件名称(应全部小写,不能有空格) |
version | 插件版本号 |
publisher | 发布者,(该名称应与发布到应用市场名称一致) |
engines | 表示插件最低支持的vscode版本 |
main | 插件的主入口 |
activationEvents | 插件触发动作,如在打开某种语言的文件时、当某个命令被触发时 |
contributes | 插件贡献点,大部分新增功能点都再次声明 |
commands | 插件命令 |
keybindings | 快捷键绑定 |
snippets | 代码片段 |
scripts | 同npm scripts |
devDependencies | 开发依赖 |
- extension.js
const vscode = require('vscode');
/**
* @param {vscode.ExtensionContext} context
* 插件被激活时触发,所有代码总入口
*/
function activate(context) {
// 使用控制台输出诊断信息(console.log)和错误(console.error);
// 扩展激活时,这行代码只执行一次
console.log('Congratulations, your extension "hello" is now active!');
// vscode.commands.registerCommand是注册命令的API,执行后会返回一个Disposable对象,所有注册类的API执行后都需要将返回结果放到context.subscriptions中去。
let disposable = vscode.commands.registerCommand('JavaScript.helloWorld', function () {
// 每次执行命令时,您在此处放置的代码都将被执行,向用户显示消息框
vscode.window.showInformationMessage('Hello World from hello!');
});
context.subscriptions.push(disposable);
}
// 插件被停用之前进行清理
function deactivate() {}
module.exports = {
activate,
deactivate
}
四 . 开发与调试
插件开发(以webview插件开发为例)
创建webview(window.createWebviewPanel)
- extension.js中引入webview主页面
const vscode = require('vscode');
/*
* 插件被激活时,所有代码总入口
*/
function activate(context) {
require('./index)(context) // 主页面
}
// 插件停用之前进行清理
function deactivate() {
console.log('扩展已被释放')
}
module.exports = {
activate,
deactivate
}
- index主页面中创建webview
module.exports = (context) => {
context.subscriptions.push(vscode.commands.registerCommand('vscode-plugin.helloWorld', () => {
const panel = vscode.window.createWebviewPanel(
'VScode-Plugin', //viewType
'VScode Plugin', //视图标题
vscode.ViewColumn.One, // 显示在编辑器的哪个部位
{
enableScripts: true, // 启用JS,默认禁用
retainContextWhenHidden: true, // webview被隐藏时保持状态,避免被重置
}
);
// 获取磁盘上资源的路径
panel.webview.html = util.getWebViewContent(context, 'src/pages/index.html');
}))
}
加载页面资源
出于安全考虑,webview无法直接访问本地资源,想要加载本地js、css、等资源必须通过特殊的vscode-resource协议。这种协议类似于file协议他只允许访问特定的本地文件并从磁盘上加载绝对路径的资源(可参考vscode插件开发全攻略提供的Git demo)
页面通信
- 消息从扩展传递到webview 扩展可以使用webview.postMessage(),此方法将任何JSON可序列化数据发送到webview,消息通过标准message事件在webview内部接收。 具体使用方法参考官方案例(code.visualstudio.com/api/extensi…)
- 消息从webview传递到扩展 webview将消息传递回扩展也是通过postMessage(),但要在webview内调用acquireVsCodeApi来访问 VS Code API 对象,每个会话只能调用此函数一次且必须挂在此方法返回的 VS Code API 的实例上,并将其分发给需要使用它的任何其他函数。
// webview页面
<body>
<div @click="updateHtml">详情</div>
</body>
// js
const vscode = acquireVsCodeApi();
new Vue({
el: '#app',
data: {},
methods: {
updateHtml() {
vscode.postMessage({
command: 'update', // 向扩展传递参数
})
}
}
})
// 扩展中接收参数
panel.webview.onDidReceiveMessage( // onDidReceiveMessage: 从渲染器接收到消息时触发的事件
message => {
switch (message.command) {
case 'update':
// 页面更新
panel.webview.html = util.getWebViewContent(context, 'src/pages/update.html');
break;
}
},
undefined,
context.subscriptions
);
生命周期 & webview状态
用户关闭webview面板后,webview自动销毁
- panel.webview.onDidReceiveMessage() 当 webview 内容发布消息时触发。 Webview 内容可以将字符串或 json 可序列化对象发布回扩展。他们不能发布Blob,File,ImageData和其他
- panel.dispose():扩展程序还可以通过调用dispose()它们以编程方式关闭 webviews (参考官方demo)
可能遇到的edit
- editor属性
- document:当前编辑器中的文档内容
- edit:用于修改编辑器中的内容
- revealRange:用于将某段代码滚动到当前窗口中
- selection: 当前编辑器内的主光标
- selections:当前编辑器中的所有光标,第一个光标就是主光标,后面的则是用户创建出来的多个光标
- setDecorations: 设置编辑器装饰器
- edit的API
- delete
- insert
- replace
- setEndOfLine
插件调试
启动webview插件
- step1:编辑器中按F5(或使用vsocde中运行和调试),在新窗口中编译和运行扩展
- step2:在新窗口命令面板中运行shift+command+p
- step3:点击自定义命令(如Hello World),打开webview页面
断点调试
- 点击要打断点的某行代码
- 启动插件
检查webview
option+command+i 打开webview调试台
五 . VS Code发布更新
打包
// 确保已安装node.js后运行
npm install -g vsce
// 依次运行如下命令
cd 项目
vsce package
vsce publish
发布扩展
获取个人访问令牌
-
登录Microsoft(无账号先到Microsoft官方注册账号)
-
创建组织(按照文档创建流程创建组织)
-
设置中选择个人访问令牌
-
创建新的 Personal Access Token
- 复制令牌创建发布者
创建发布者
发布扩展
- 发布扩展
vsce publish //处于安全考虑vsce不会发布包含用户提供的 SVG 图像的扩展
- 自动增值扩展
//如果将扩展的版本从 1.0.0 更新到 1.1.0,您可以指定minor:
vsce publish minor
//还可以在命令行上指定完整的 SemVer 兼容版本
vsce publish 2.0.1
取消发布
vsce unpublish (publisher name).(extension name) //注意:此操作是直接删除插件
用户更新
vscode插件更新是热更新的模式,安装后有更新会自动检测新版本,用户只需搜索插件后重启开插件即可