记一次前端 ”vscode 插件编写实战 ” 超具体的分享会(上)
记录了我在组内的技术分享, 有同样需要的同学能够参考一下
分享全程下来工夫大概 77 分钟
一. vscode 咱们的战友
vscode 自身都是用浏览器实现的, 应用的技术为 Electron, 能够说 vscode 自身对咱们前端工程师很敌对, 在 vscode 上有很多优良的插件供开发者应用, 那你有没有想过开发一款适宜本人团队应用的插件?
写文章之前我在网上找了很多材料, 但视频方面的材料太少了, 官方网站也并没有被很好很残缺的汉化, 文章还是有一些的但大多举的例子不好运行, 须要读者本人配置一堆货色, 官网到是提供了再 github 上的一套例子, 但都是用 ts 编写并且局部运行都有问题, 外面的思维逻辑与书写形式也不适宜入门学习, 所以我才在此写一篇更加易懂的分享教程, 心愿能够让刚入门的同学更好的学习起来, 话不多说咱们一步步深刻摸索.
二. 环境的筹备.
- node 这个不用说了吧, 前端必备
- git
- npm install -g yo generator-code 装置开发工具, 这个 yo 是帮忙咱们创立我的项目的, 你能够了解为 cli
初始化我的项目
yo code
尽管很短小, 但没错就是这样的
这里须要咱们抉择初始化的工程, 这里咱们次要聊插件局部, 并且 ts 并不是探讨的重点所以咱们抉择第二个 JavaScript
, 如果选第一个就会是应用 ts 开发插件.
输出一个插件名字, package.json 中的 displayName 也会变成这个
是否也采纳 () 内的名字, 我的项目名也是文件夹名, package.json 中的 name 属性也会变成这个
输出对这个插件的形容, 我的项目名也是文件夹名, package.json 中的 description 属性也会变成这个
在 js 文件中启动语义检测 (可能用不到), jsconfig.json 中 compilerOptions.checkJs 会变为 true
是否初始化 git 仓库
抉择钟爱的包治理形式
做完上述的步骤咱们就失去了一个繁难的工程
为了局部第一次做插件的同学入门, 这里临时就不改变目录构造了, 上面介绍完配置咱们在一起优化这个我的项目的构造.
三. 官网的第一个例子, 兴许并不太适宜入门时了解
extension.js
这个文件是初始我的项目时的入口文件, 咱们的故事就是在这里开展的, 咱们先把外面的正文都清理掉, 我来逐个解读一下这个根底构造.
初始化的外面有点乱, 大家能够把我上面这份代码粘贴进去, 看着舒爽多了.
const vscode = require('vscode');
function activate(context) {
// 1: 这里执行插件被激活时的操作
console.log('我被激活了!! 桀桀桀桀...')
// 1: 定义了一个命令(vscode.commands)
// 2: lulu.helloWorld 能够把它当做 id
let disposable = vscode.commands.registerCommand('lulu.helloWorld', function () {
// 3: 触发了一个弹出框
vscode.window.showInformationMessage('第一个 demo 弹出信息!');
});
// 4: 把这个对象放入上下文中, 使其失效
context.subscriptions.push(disposable);
}
// 5: 插件被销毁时调用的办法, 比方能够革除一些缓存, 开释一些内存
function deactivate() {}
// 6: 忙活一大堆当然要导出
module.exports = {
activate,
deactivate
}
下面曾经具体的标注了每一句代码, 接下来咱们 按 F5
进入调试模式如图.
- 上方会呈现一个操作栏, 咱们接下来会常常与最初两个打交道
- 零碎为咱们新开了一个窗口, 这个窗口默认集成了咱们以后开发的这个插件工程
下方也会呈现调试台, 咱们插件外面 console.log 打印的信息都会呈现在这里.
官网这个例子须要咱们 ctrl + shirt + p
调出输入框, 而后在外面输出hello w
就能够如图所示
使劲狠狠敲击回车, 大喊 神之一手
, 响起 bgm
在左下角就会呈现这样一个弹出款, 这个例子也就实现了
组件显示被激活
那么咱们一起来看一下, 这一套流程到底是怎么配置进去的!!
他的配置形式我比拟不同意, 都是在 package.json 外面进行的
package.json
activationEvents
: 当什么状况下, 去激活这个插件, 也就是下面打印出桀桀怪笑.activationEvents.onCommand
: 在某个命令下激活 ( 之后会专门列出很多其余条件
)
定义命令
contributes.commands
: 你能够了解为 ’ 命令 ’ 的列表command
: 命令的 id (下面就是依附这个 id 找到这个命令)title
: 命令语句(能够看下图)
所以 extension.js
外面的registerCommand('lulu.helloWorld'
就是指定了, 这个命令 Id 被执行的时候, 该执行的操作!
let disposable = vscode.commands.registerCommand('lulu.helloWorld', function () {
// 3: 触发了一个弹出框
vscode.window.showInformationMessage('第一个 demo 弹出信息!');
});
之所以题目里说这个例子不是太好, 就是因为咱们平时较少用 vscode 的命令去做某个操作, 并不会很活泼的把咱们带入进去
四. 我的项目构造微改 + 提醒的类型
一个 extension.js
文件曾经满足不了咱们的 ’xie.nian’ 了, 所以咱们要把它略微革新一下.
老朋友 src
出场了, 毕竟咱们当前要封装很多命令与操作,工程化一点是必要的.
- 最外层新建 src 文件夹
extension.js
改名index.js
, 放入 src 文件夹内.package.json
中设置门路 “main”: “./src/index.js”(重点入口文件)- 新建“目录.md”文件,把插件的简介欠缺一下,保障任何时候最快速度了解我的项目。
- 新建
message.js
文件, 搁置弹出信息代码.
index 文件: 只负责导出引入各种性能, 不做具体的操作
const message = require('./message.js');
function activate(context) {context.subscriptions.push(message);
}
module.exports = {activate}
message.js
触发各种提示框
const vscode = require('vscode');
module.exports = vscode.commands.registerCommand('lulu.helloWorld', function () {vscode.window.showInformationMessage('第一个 demo 弹出信息!');
vscode.window.showWarningMessage('第一个正告信息')
vscode.window.showErrorMessage('第一个错误信息!');
});
目录.md(这个要随时更新不要偷懒)
# 目录
1. index 入口文件
2. message 提示信息插件
3.
成果如下:
五. 激活的机会
出于性能的思考, 咱们的组件并不是任何时候都无效的, 也就是说不到对应的机会咱们的组件处于未被激活的状态, 只有当比如说遇到 js
文件才会失效, 遇到 scss
文件才会失效, 只能某个命令能力失效等等状况.
在 package.json
的activationEvents 数组
属性外面进行批改.
这里只是罕用的类型, 具体的能够去官网文档查看.
"activationEvents": [
"onCommand:hello.cc", // 执行 hello 命令时激活组件
"onLanguage:javascript", // 只有是 js 文件的时候激活组件(你能够做 js 的代码检测插件)
"onLanguage:python", // 过后 py 文件的时候
"onLanguage:json",
"onLanguage:markdown",
"onLanguage:typescript",
"onDebug", // 这种生命周期的也有
"*",
"onStartupFinished"
],
- “*” 就是进来就激活, 因为他是任何机会(不倡议应用这个).
onStartupFinished
他就敌对多了, 相当于 然而他是提早执行, 不会影响启动速度, 因为他是浏览器启动完结后调用(非要用 ”“ 能够用这个代替).
这里有个坑点, 比方你有 a,b 两个命令, 把 a 命令设为触发机会, 那么如果先执行 b 命令会报错, 因为你的插件还未激活.
六. 生命周期
与其余库一样, 生命周期是必不可少的 ( 摘自官网).
onLanguage
onCommand
-
onDebug
onDebugInitialConfigurations
onDebugResolve
workspaceContains
onFileSystem
onView
onUri
onWebviewPanel
onCustomEditor
*
onStartupFinished
七. window 与 mac 的区别
咱们晓得, window 与 mac 的案件是不大一样的, mac 更多是应用 command
键, 这里我介绍一下别离设置快捷键.
在` 外面
contributes` 属性
"keybindings": [
{
"command": "hello.cc",
"key": "ctrl+f10",
"mac": "cmd+f10",
"when": "editorTextFocus"
}
],
八. when 属性罕用形式
接下来还有其余中央用到这个 when 属性
那么这里就专门提一下吧
上面是比拟罕用的, 具体的要查官网, 毕竟太多了!
1. 编辑器取得焦点时
"when": "editorFocus"
2. 编辑器文本取得焦点
"when": "editorTextFocus"
3. 编辑器获取焦点并且四 js 文件的时候
"when": "editorFocus && resourceLangId == javascript"
4. 后缀不为.js
"when":"resourceExtname != .js"
5. 只在 Linux,Windows 环境下失效
"when": "isLinux || isWindows"
1. 要正确的了解 when
, 他不是字符串, 他是 true 或 false 的布尔, 写成字符串 vscode 会去解析的, 所以when
能够间接传 true, false, 这里要留神, 是when: "true" when:"false"
2. 由第一条可知 editorLangId
其实就是运行时上下文的一个变量, 也就是文件类型名常量.
参考资料: https://code.visualstudio.com…
九. 所在的地位 左侧, 右上, 菜单的上与下
这里也只介绍最罕用与好用的, 很多偏门常识学了我的这篇文章你也肯定能够很轻易的自学了.
①. 鼠标右键
新建 navigation.js
文件用来展现咱们的性能是否失效.
在 index.js
外面引入
const vscode = require('vscode');
const message = require('./message.js');
const navigation = require('./navigation.js');
function activate(context) {vscode.window.showInformationMessage('插件胜利激活!');
context.subscriptions.push(message);
context.subscriptions.push(navigation);
}
module.exports = {activate}
const vscode = require('vscode');
module.exports = vscode.commands.registerCommand('lulu.nav', function () {let day = new Date();
day.setTime(day.getTime() + 24 * 60 * 60 * 1000);
let date = day.getFullYear() + "-" + (day.getMonth() + 1) + "-" + day.getDate();
vscode.window.showInformationMessage(` 今天是: ${date}`);
});
下面是一个报告今天日期的性能, 当然咱们能够在这里申请后端接口, 调取明天的人员安顿列表之类的接口.
package.json
外面的 contributes
属性中增加导航的配置.
1: 定义一个命令, 而后上面定义快捷触发这个命令
"commands": [
{
"command": "lulu.nav",
"title": "点击我进行导航操作"
}
],
2: 定义导航内容, 并且绑定点击事件
"menus": {
// 在编辑器的内容区域
"editor/context": [
{
"when": "editorFocus", // 你懂得
"command": "lulu.nav", // 援用命令
"group": "navigation" // 放在导航最上方
}
]
}
②. 右上按钮
其实挺少有插件用这里的, 反而这里的市场没被占用, 想开发插件的同学能够领先霸占一下.
"menus": {
"editor/title": [
{
"when": "editorFocus", // 你懂得
"command": "lulu.nav", // 援用命令
"group": "navigation" // 放在导航最上方
}
]
}
③. 左侧导航栏, (这个我决定上面与 tree 一起讲, 因为那里是重点)
十. 加载的进度条(官网例子含糊)
加载是很罕用的性能, 然而官网的例子也的确不够敌对, 本着 我踩过的坑就不心愿他人踩
的准则这里讲下进度条的理论用法.
老套路定义好命令
{
"command": "lulu.progress",
"title": "显示进度条"
}
为了不便 咱们把它也定义在右键菜单外面
{
"when": "editorFocus",
"command": "lulu.progress",
"group": "navigation"
}
新建 progress.js
文件
const vscode = require('vscode');
module.exports = vscode.commands.registerCommand('lulu.progress', function () {
vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: "载入 xxxx 的进度...",
cancellable: true
}, (progress) => {
// 初始化进度
progress.report({increment: 0});
setTimeout(() => {progress.report({ increment: 10, message: "在致力。。。."});
}, 1000);
setTimeout(() => {progress.report({ increment: 40, message: "马上了..."});
}, 2000);
setTimeout(() => {progress.report({ increment: 50, message: "这就完结..."});
}, 3000);
const p = new Promise(resolve => {setTimeout(() => {resolve();
}, 5000);
});
return p;
})
});
vscode.window.withProgress
第一个参数是配置, 第二个参数是操作vscode.ProgressLocation.Notification
起源信息, 让用户晓得是哪个插件的进度条title
加载框题目cancellable
是否可勾销progress.report
初始化进度message
拼在 title 前面的字符- 因为返回的是 promise, 所以规定调用
resolve
则完结进度
进度条也算罕用的基本功能, 好好用让本人的插件更敌对.