前言
console.log
是window上的一个常用方法,该函数可以把各种信息打印输出到浏览器控制台,以便开发者进行调试、定位问题。
在代码量很少的情况下,多次使用console.log
,开发者还能勉强在控制台找到自己想要的信息。eg:
var student={
name:"zhangsan",
age:12
}
console.log(student.name)
var teacher={
name:"zhangsan",
age:21
}
console.log(teacher.name)
/**
*控制台输出
* zhangsan
* zhangsan
* 巧了,老师和学生同名了,没关系,控制台第一行输出的是学生姓名,第二行输出的是老师姓名,反正我能区分出来。
*/
复制代码
在代码量比较多、团队合作的项目中,大量的consol.log
被调用,控制台简直惨不忍睹,信息虽然很多,但很难找到自己输出的那个,为了解决这个问题,很多开发者都会在打印信息的前面加上前缀进行区分。eg:
// 还用上面的student和teacher举栗
console.log("student.name=======",student.name)
console.log("teacher.name=======",teacher.name)
...
/**
*控制台输出
* student.name======= zhangsan
* teacher.name======= zhangsan
* 简直就是一个字,"清爽"
*/
复制代码
爽是爽了,可是还有一个问题,加前缀对于开发人员来说可是个体力活,写起来很累。于是就有了本次需求(实现这种加前缀打印的功能),因为现在大部分前端开发人员都使用vscode,所以就基于vscode编辑器开发这样一个插件,实现解决痛点并提高开发效率的小目标。
准备工作
- npm install yo generator-code -g
- yo code
- 根据提示完成命令行交互
ok,一个vscode插件项目的脚手架就生成了!
目录结构介绍
整个目录结构比较简单,重点关注package.json
和extension.js
这两个文件。
目录
.
├── CHANGELOG.md
├── README.md
├── extension.js // 入口
├── jsconfig.json
├── node_modules
├── package-lock.json
├── package.json // 项目配置
├── test
└── vsc-extension-quickstart.md
复制代码
package.json
{
...略
"activationEvents": [ // 激活事件列表
"onCommand:extension.helloWorld" // 表示extension.helloWorld这个插件只能通过命令的方式激活
],
"main": "./extension.js", // 入口文件
"contributes": { // 贡献点
"commands": [{ // 命令列表
"command": "extension.helloWorld", // 命令的名称,必须和入口文件中注册的名称保持一致
"title": "Hello World" // 通过命令面板调用时的名称
}]
},
...略
}
复制代码
extension.js
const vscode = require('vscode');
// 插件被激活时调用
// context是一个插件的上下文环境
function activate(context) {
// 通过registerCommand API 注册命令
// 参数extension.helloWorld必须和package.json中的保持一致
// 返回一个disposable对象
let disposable = vscode.commands.registerCommand('extension.helloWorld', function () {
// 通过showInformationMessage API 弹窗展示信息
vscode.window.showInformationMessage('Hello World!');
});
// 把disposable对象加入上下文的订阅列表中
context.subscriptions.push(disposable);
}
exports.activate = activate;
// 插件被停止时调用
function deactivate() {}
// 导出该模块
module.exports = {
activate,
deactivate
}
复制代码
hello world跑起来
生成的项目自带一个hello world
插件的demo,供开发人员借鉴。用vscode打开刚才生成的项目,按下键盘上的F5
键进入调试模式,这时候会打开一个新窗口供插件运行,在新窗口中按下command+shift+p
键打开命令面板,输入在package.json
中定义命令时title
对应的值,这时候编辑器右下角就会弹出一条内容为Hello World!
的信息。试着把extension.js
中的代码做一些修改,重启一下调试模式,就会看到相应的变化。
###站在巨人的肩膀上
通过上面的介绍,就可以进行插件的开发和调试了,直接在官方demo上进行扩展和修改。继续在package.json
和extension.js
这两个文件上做文章。
package.json中主要修改项目的基本配置,比如名称、版本、命令等,增加一些额外的配置项,比如代码仓库、命令快捷键列表、发布者等,以下是package.json
中修改和新增的内容。
{
"name": "vscode-prefix-log", // 插件的名称
"displayName": "vscode-prefix-log", // 在扩展市场中插件的名字
"description": "console with prefix", // 对插件的描述
"version": "0.0.1", // 版本
"repository": { // 关联的代码管理库 repository最好配置上,否则在插件发布的时候会警告
"type": "git",
"url": "https://github.com/xxx/vscode-prefix-log"
},
"activationEvents": [
"onCommand:console.with.prefix"
],
"main": "./extension.js",
"contributes": {
"commands": [
{
"command": "console.with.prefix",
"title": "prefix.log"
}
],
"keybindings": [ // 命令快捷键列表 除了在命令面板输入title,也可以使用快捷键触发命令
{
"command": "console.with.prefix",
"key": "shift+d", // 快捷键
"when": "editorTextFocus" // 当编辑器的文本在聚焦的时候快捷键才起作用
}
]
},
"publisher": "xxx" // 发布者
...略
}
复制代码
extension.js 保持代码结构不变,重写activate方法,因为要开发的插件是跟编辑器文本相关,所以主要用到了vscode中跟文本编辑相关的API,比如onDidChangeActiveTextEditor
、getWordRangeAtPosition
等。
function activate(context) {
console.log('Congratulations, your extension "vscode-prefix-log" is now active!');
// 获取当前编辑器对象
let currentEditor = vscode.window.activeTextEditor;
// 当编辑器文本变化时,重置编辑器对象
vscode.window.onDidChangeActiveTextEditor(editor => (currentEditor = editor));
// 注册命令
const disposable = vscode.commands.registerTextEditorCommand('console.with.prefix', () => {
new Promise((resolve, reject) => {
let sel = currentEditor.selection; // 获取选中区域
const reg = /[\S]+\.(log)$/; // 规定匹配log的正则
// 通过getWordRangeAtPosition方法得到单词范围对象
let ran = currentEditor.document.getWordRangeAtPosition(sel.anchor, reg);
if (ran == undefined) {
reject('please use this statements:xxx.log');
} else {
let doc = currentEditor.document; // 获取当前文档对象
let line = ran.start.line; // 获取行数
let item = doc.getText(ran); // 通过getText方法获取文本
let prefix = item.replace('.log', '');
// 获取当前行的第一个非空字符的偏移量
let idx = doc.lineAt(line).firstNonWhitespaceCharacterIndex;
let wrapData = {
idx,
ran,
line,
txt: `console.log('${prefix}========',${prefix});`
};
resolve(wrapData);
}
}).then(wrap => {
currentEditor
.edit(e => {
// 将旧文本替换成新文本 主要的功能就是靠这行代码实现
e.replace(wrap.ran, wrap.txt);
}).then(() => {
// 把光标定位到末尾
currentEditor.selection = new vscode.Selection(
new vscode.Position(wrap.line, wrap.txt.length + wrap.idx),
new vscode.Position(wrap.line, wrap.txt.length + wrap.idx)
);
});
}).catch(message => {
console.log('REJECTED_PROMISE:' + message);
});
});
context.subscriptions.push(disposable);
}
复制代码
接下来,保存代码,按下F5键进行调试,结果如下图。
插件发布及使用
插件开发好了,小伙伴们怎么才能使用呢,简单的方法就是直接将项目copy到vscode的扩展目录中,重启下vscode就可以使用了(只能小范围使用)。比较推荐的做法是将开发好的插件通过vsce
这个工具发布到vscode的应用市场,类似于把node包发布到npm上,首次发布稍微会有点繁琐,具体流程可以参考网上的一篇博文。当在控制台看到如下提示就表明发布成功了。
DONE Published xxx.vscode-prefix-log@0.0.7
Your extension will live at https://marketplace.visualstudio.com/items?itemName=zhangleilei.vscode-prefix-log
(might take a few seconds for it to show up).
复制代码
发布成功后,就可以在vscode的应用市场通过名字找到插件了,只要是vscode用户都可以愉快的安装并使用了。
后语
有兴趣的同学可以基于此插件进一步扩展,比如打印的时候输出文件名、行号等信息,这样就可以精准定位了。本文最多算一篇入门科普,如果想要把事情搞大,那就去多看看vscode
的API和别人家开发的插件代码。
代码地址 github.com/qinhangong/…