更多文章请戳VSCode插件开发全攻略系列目录导航

前言

在介绍完一些比较简单的内容点之后,我觉得有必要先和大家介绍一些开发中遇到的一些细节问题以及技巧,特别是后面一章节将要介绍WebView的知识,这个坑会比较多,避免大家走弯路。

开发方式

最理想的方式是准备双显示器,一个写代码,一个运行插件,实践证明这种方式开发效率会提升很多,每次修改完代码之后直接Ctrl+R重新加载即可,非常方便。

日志查看

就我目前遇到的情况来看,vscode日志主要有这5种:

旧窗口的调试控制台

扩展里的console.log()日志一般输出在这里,但是有很大的限制,结构稍微深一点的对象在这里了就显示不了:

Unable to log remote console arguments Output omitted for an object that cannot be inspected (Error: [sxei.vscode-plugin-demo]: Proposed API is only available when running out of dev or with the following command line switch: --enable-proposed-api sxei.vscode-plugin-demo)

这里只能看成是新窗口开发者控制台日志的一种快捷显示,以下是旧窗口调试控制台显示的内容:

而对应的内容在新窗口的开发者控制台显示如下:

可以看到,结构较深的对象即使在控制台也无法显示,目前发现的唯一比较好的方法就是在输出的地方打一个断点,然后运行的时候会自动卡在这里,鼠标悬停就可以查看对象的内容。

新窗口的调试控制台

一般没什么扩展相关日志会输出在这里。

旧窗口的开发者控制台

快捷键Ctrl+Alt+I,这里一般显示vscode本身一些日志,和扩展相关的不会显示在这里,所以这个也不用太多关心。

新窗口的开发者控制台

快捷键也是Ctrl+Alt+I,不记得的可以从帮助 -> 切换开发人员工具找到。这个控制台很重要,有时候如果发现你的代码莫名其妙没生效,很有可能是报错了,这种报错是不会显示在旧窗口调试控制台的,如果你不知道到这里来查看日志,那么你只能一脸懵逼的到处乱试了,调试控制台只打印常规日志,语法错误并不会显示在这里。

例如,我在跳转定义实现前人为制造一个错误:

function provideDefinition(document, position, token) {
console.log(aaf);
const fileName = document.fileName;
// 省略其它代码
}

运行后就会发现点击跳转不生效,但是也没有什么报错提示,此时只能打开控制台查看才能发现问题:

WebView控制台

WebView我们会在下一章节介绍,这里先提一下。Webview的控制台比较特殊,需要特殊的命令才能打开,按下Ctrl+Shift+P然后执行打开Webview开发工具,英文版应该是Open Webview Developer Tools

开发时我们把它当成一个普通的网页来看就好了。

调试

vscode插件的调试非常简单方便,只需要在需要调试的地方打个断点,然后按F5执行即可:

几个调试快捷键:

  • F5运行
  • Ctrl+F2停止运行
  • F6下一步跳过(类似于Chrome的F10
  • F5下一步跳入
  • F8跳过

如何快速找到我想找的内容

刚开始只能先大概对整个vscode的api有一个大概了解,了解了之后就大概清楚一般什么功能会怎么实现,该去什么地方找,所有的vscode的api都可以在vscode.d.ts文件里面找到:

不得不佩服,正规大型项目的注释写的真的不是一般的详细,官网的API文档肯定也是基于这个自动生成的,反正把这个ts文件吃透了,基本上你想实现什么功能要怎么实现都了如指掌了。

查看插件存放目录

插件安装后根据操作系统不同会放在如下目录:

  • Windows系统:%USERPROFILE%\.vscode\extensions
  • Mac/Linux:~/.vscode/extensions

想要学习查看其它插件的代码可以找到这个目录:

一些个人经验分享

调试控制台日志不可靠

vscode有一个很坑爹的地方,这里特别要注意,当require一个function进来并打印输出时,虽然打印在控制台显示为null,但其实是有值的,不知道的人很容易被误导,直接就是被这个现象骗了很久,切记切记

test-require-function.js:

function testRequireFunction(a, b) {
console.log('进入testRequireFunction方法');
console.log(a, b);
}
module.exports = testRequireFunction;

extension.js

exports.activate = function(context) {
const testFn = require('./test-require-function');
console.log(testFn); // vscode的日志输出不可靠,这里竟然会打印null?!
testFn(1, 2); // 1, 2
};

输出结果:

null
进入testRequireFunction方法
1 2

代码为什么没生效

代码没生效一般从这几个地方去查找:

  • activationEvents里面添加了吗?开发的时候如果老是忘记可以直接设置成*
  • 代码是不是报错了?如前文所说,很多错误是不会暴露出来的,需要手动打开控制台查看;
  • 代码是不是忘记引入了?有时候拆分多个文件之后可能忘了引入;
  • 逻辑是不是写错了?最好的办法就是debug,这是找问题最快的方法;
  • 版本冲突

这里重点说一下最后面的版本冲突,这个甚至可以说是vscode本身的一些bug,经常发现代码莫名其妙地没生效,怎么调试都不对,后来发现运行的根本就不是我们正在开发的那个版本,特别是当你的插件已经发了一版到应用市场并安装后,本地再按F5运行,理论上说debug运行的会覆盖已安装的,但有时候还是会出现异常情况,所以为了以防万一,当出现这种情况时可以先把已经安装的给卸载。

还有一个问题就是,有时候明明安装了版本更加新的那个,结果运行的却是旧的,打开扩展目录会发现很多并存的同名不同版本插件,或者可能先是通过vsix方式安装了一个版本,然后又从应用市场安装一个,总之解决这类问题最好的方法就是:先卸载再安装,实在不行手动去插件目录删除之!

打开文件

打开文件是vscode.window.showTextDocument而不是vscode.workspace.openTextDocument,这个根据字面意思很容易搞错,原来老外也有命名不准确的时候啊,哈哈。

  • vscode.workspace.openTextDocument仅仅是加载文档并返回一个TextDocument对象,但是并不在vscode中打开;
  • vscode.window.showTextDocument则是在vscode中打开一个文档;

其实:

vscode.workspace.openTextDocument('someFilePath').then(document => {
vscode.window.showTextDocument(document, editor => {
// 可以操作文档的editor对象
});
})

等价于:

vscode.window.showTextDocument(vscode.Uri.file('someFilePath'), editor => {
// 可以操作文档的editor对象
});

工程根目录的获取

被这个问题踩过很多次坑,所有重点介绍一下。

有的人的vscode工作空间是这样的,每一个工程一个个地单独拖入:

也有的人是直接用打开文件夹的方式把存放代码的父文件夹给打开:

但是如果此时你点击将工作区另存为保存了工作区之后就变成这样了(请注意图标的变化):

所以,即便拿到了某个文件的完整路径也不好获取这个文件的工程路径,因为不知道工作区的这个文件夹名字是你的工程名还是存放工程的父文件夹的名字。

已知:

  • vscode以前有一个vscode.workspace.rootPath,由于后来vscode支持multipleRoot模式,所以这个字段已经过时作废了。
  • vscode.workspace.workspaceFolders可以获取当前工作区所有根文件夹数组;

之前我写了一个简单粗暴的获取工程目录方式:

/**
* 获取当前所在工程根目录,有3种使用方法:<br>
* getProjectPath(uri) uri 表示工程内某个文件的路径<br>
* getProjectPath(document) document 表示当前被打开的文件document对象<br>
* getProjectPath() 会自动从 activeTextEditor 拿document对象,如果没有拿到则报错
* @param {*} document
*/
getProjectPath(document) {
if (!document) {
document = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.document : null;
}
if (!document) {
this.showError('当前激活的编辑器不是文件或者没有文件被打开!');
return '';
}
const currentFile = (document.uri ? document.uri : document).fsPath;
let projectPath = null; let workspaceFolders = vscode.workspace.workspaceFolders.map(item => item.uri.path);
// 由于存在Multi-root工作区,暂时没有特别好的判断方法,先这样粗暴判断
// 如果发现只有一个根文件夹,读取其子文件夹作为 workspaceFolders
if (workspaceFolders.length == 1 && workspaceFolders[0] === vscode.workspace.rootPath) {
const rootPath = workspaceFolders[0];
var files = fs.readdirSync(rootPath);
workspaceFolders = files.filter(name => !/^\./g.test(name)).map(name => path.resolve(rootPath, name));
// vscode.workspace.rootPath会不准确,且已过时
// return vscode.workspace.rootPath + '/' + this._getProjectName(vscode, document);
}
workspaceFolders.forEach(folder => {
if (currentFile.indexOf(folder) === 0) {
projectPath = folder;
}
})
if (!projectPath) {
this.showError('获取工程根路径异常!');
return '';
}
return projectPath;
},

这种方式生效的前提是,如果是按照第一种方式存放工作空间的,工程的数目必须大于等于2,但是这种判断方式不用说肯定会不准确。

后来换成了另外一种方式,考虑到工作接触到的项目无论是node端还是前端都会有package.json文件在根目录,所以就根据哪个文件夹有这个文件来判断,也只能是这样了。

VSCode插件开发全攻略(六)开发调试技巧的更多相关文章

  1. VSCode插件开发全攻略(一)概览

    文章索引 VSCode插件开发全攻略(一)概览 VSCode插件开发全攻略(二)HelloWord VSCode插件开发全攻略(三)package.json详解 VSCode插件开发全攻略(四)命令. ...

  2. VSCode插件开发全攻略(七)WebView

    更多文章请戳VSCode插件开发全攻略系列目录导航. 什么是Webview 大家都知道,整个VSCode编辑器就是一张大的网页,其实,我们还可以在Visual Studio Code中创建完全自定义的 ...

  3. VSCode插件开发全攻略(三)package.json详解

    更多文章请戳VSCode插件开发全攻略系列目录导航. package.json 在详细介绍vscode插件开发细节之前,这里我们先详细介绍一下vscode插件的package.json写法,但是建议先 ...

  4. VSCode插件开发全攻略(二)HelloWord

    更多文章请戳VSCode插件开发全攻略系列目录导航. 写着前面 学习一门新的语言或者生态首先肯定是从HelloWord开始. 您可以直接克隆我放在GitHub上vscode-plugin-demo 的 ...

  5. VSCode插件开发全攻略(四)命令、菜单、快捷键

    更多文章请戳VSCode插件开发全攻略系列目录导航. 命令 我们在前面HelloWord章节中已经提到了命令写法,这里再重温一下. context.subscriptions.push(vscode. ...

  6. VSCode插件开发全攻略(九)常用API总结

    更多文章请戳VSCode插件开发全攻略系列目录导航. 本文提炼一些常见的API使用场景供参考,本文内容有待完善. 编辑器相关 修改当前激活编辑器内容 替换当前编辑器全部内容: vscode.windo ...

  7. VSCode插件开发全攻略(十)打包、发布、升级

    更多文章请戳VSCode插件开发全攻略系列目录导航. 发布方式 插件开发完了,如何发布出去分享给他人呢?主要有3种方法: 方法一:直接把文件夹发给别人,让别人找到vscode的插件存放目录并放进去,然 ...

  8. VSCode插件开发全攻略(八)代码片段、设置、自定义欢迎页

    更多文章请戳VSCode插件开发全攻略系列目录导航. 代码片段 代码片段,也叫snippets,相信大家都不陌生,就是输入一个很简单的单词然后一回车带出来很多代码.平时大家也可以直接在vscode中创 ...

  9. VSCode插件开发全攻略(五)跳转到定义、自动补全、悬停提示

    更多文章请戳VSCode插件开发全攻略系列目录导航. 跳转到定义 跳转到定义其实很简单,通过vscode.languages.registerDefinitionProvider注册一个provide ...

随机推荐

  1. 【Spring学习】【Java基础回顾-数据类型】

    Java基础回顾过程中,之前对于Java相关基础知识都是从这个人的博客看一些,那边的内容看一下,觉得不够系统化,决定用xmind脑图的形式,将Java基础知识回顾的作为一个系列,当前正在做的会包含: ...

  2. redis集群搭建及设置账户(转)

    Redis集群搭建以及为集群设置密码 介绍安装环境与版本 用两台虚拟机模拟6个节点,一台机器3个节点,创建出3 master.3 salve 环境. redis 采用 redis-3.2.4 版本. ...

  3. $.ajax()参数详解

    来自于<锋利的jQuery(第2版)>. 参数 类型 说明 accepts Map 内容类型发送请求头,告诉服务器什么样的响应会接受返回. 如果accepts设置需要修改,推荐在$.aja ...

  4. 后台跨域(CORS)

    解决跨域问题 一.为什么会有跨域问题? 是因为浏览器的同源策略是对ajax请求进行阻拦了,但是不是所有的请求都给做跨域,像是一般的href属性,a标签什么的都不拦截. 二.解决跨域问题的两种方式 JS ...

  5. 结对项目——四则运算GUI项目

    一.项目地址:https://git.coding.net/lvgx/wsz.git 二.PSP: PSP2.1 任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min) Plannin ...

  6. 记录学习WeakReference发现的问题

    在学习ThreadLocal时发现ThreadLocalMap里的Entry使用到了WeakReference,所以重新学习WeakReference 查看相关博客例如: https://blog.c ...

  7. java中的 java.util.concurrent.locks.ReentrantLock类的使用方式

    实现了lock的类为:ReentrantLock 接口的方式解释: lock()方法为获取锁对象,如果未获取到锁就一直获取锁. trylock():为布尔值,返回是否获取到了锁,如果没有获取到锁则返回 ...

  8. xml代码修改图片颜色

    <?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http ...

  9. vue-cli 第二章 (常见问题修正)

    一.编译打包多出 *.map 文件处理   当执行 npm run build 后根目录下会编译出一个 dist 的文件夹,如下:     其中 css 和 js  文件夹下会多出一些 *.map 的 ...

  10. 整合 springboot 和 swagger出问题

    整合 springboot 和 swagger ,出现报错, org.springframework.beans.factory.UnsatisfiedDependencyException: Err ...