记一次前端"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
则完结进度
进度条也算罕用的基本功能, 好好用让本人的插件更敌对.