前言
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.7Your 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
的和别人家开发的插件代码。
代码地址