VSCode plug-in development strategy (6) development and debugging skills

For more articles, please poke the VSCode plug-in development full strategy series directory navigation .

foreword

After introducing some relatively simple content points, I think it is necessary to introduce some details and skills encountered in the development, especially the knowledge of WebView will be introduced in the next chapter, this pit will be more, avoid Everyone takes a detour.

development method

The most ideal way is to prepare dual monitors, one to write code and one to run the plug-in. Practice has proved that this method will improve the development efficiency a lot, Ctrl+Rand it is very convenient to reload directly after each modification of the code.

log view

As far as I am currently experiencing, there are mainly five types of vscode logs:

Debug console for old windows

The logs in the extension are console.log()generally output here, but there are great restrictions. Objects with a slightly deeper structure cannot be displayed here:

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)

This can only be regarded as a quick display of the developer console log of the new window. The following is the content displayed in the debugging console of the old window:

352797-20181016092524198-2128000609.png

The corresponding content is displayed in the developer console of the new window as follows:

352797-20181016092542113-1079237606.png

It can be seen that objects with deeper structures cannot be displayed even in the console. The only better method found so far is to hit a breakpoint at the output place, and then it will be automatically stuck here when running, and the mouse can be hovered. View the contents of the object.

352797-20181016092559813-140401356.png

Debug console in new window

Usually no extension related logs will be output here.

Developer console for old windows

Shortcut keys Ctrl+Alt+I, some logs of vscode itself are generally displayed here, and those related to extensions will not be displayed here, so don't worry too much about this.

New window developer console

The shortcut key is also Ctrl+Alt+I, if you don't remember it, you can find it from 帮助-> 切换开发人员工具. This console is very important. Sometimes if you find that your code does not take effect for some reason, it is likely to report an error. This kind of error will not be displayed 旧窗口调试控制台. If you don't know how to check the log here, then you can only look at it. I tried everywhere, the debug console only prints regular logs, and syntax errors are not displayed here.

For example, I artificially create an error before the jump definition implementation:

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

After running, you will find that clicking the jump does not take effect, but there is no error message. At this time, you can only open the console to view to find the problem:

352797-20181016092831383-554527682.png

WebViewConsole

WebViewWe will introduce it in the next chapter, but mention it here first. WebviewThe console is special and requires a special command to open, press Ctrl+Shift+Pand execute 打开Webview开发工具, the English version should be Open Webview Developer Tools:

352797-20181016092855266-1904942237.png

When developing, we just treat it as a normal web page.

debugging

The debugging of the vscode plugin is very simple and convenient, just make a breakpoint where you need to debug, and then press F5execute:

352797-20181016092935660-1039810316.png

Several debugging shortcuts:

  • F5run
  • Ctrl+F2stop running
  • F6Skip next step (similar to Chrome's F10)
  • F5jump in next
  • F8jump over

How to quickly find what I'm looking for

At the beginning, I can only have a general understanding of the entire vscode api. After understanding, I will have a general idea of ​​how the functions will be implemented and where to find them. All the vscode apis can be found in the vscode.d.tsfile:

352797-20181016093008271-1545026665.png

I have to admire that the annotations of regular large-scale projects are really not general and detailed. The API documentation of the official website must also be automatically generated based on this. Anyway, after reading this tsdocument thoroughly, basically you know exactly how to implement the functions you want to achieve. .

View the plugin storage directory

After the plugin is installed, it will be placed in the following directory depending on the operating system:

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

If you want to learn to view the code of other plugins, you can find this directory:

352797-20181016093021874-1771606398.png

Some personal experiences to share

Debug console logs are unreliable

There is a very pitiful place in vscode. Special attention should be paid here. When a require function comes in and prints the output, although it is displayed as null on the console, it is actually valuable. People who don’t know can easily be misled. Been deceived by this phenomenon for a long time, remember to remember !

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
};

Output result:

null
进入testRequireFunction方法
1 2

why the code doesn't work

If the code does not take effect, it is generally found in these places:

  • activationEventsDid you add it in? If you always forget during development, you can set it directly to *;
  • Is the code reporting an error? As mentioned above, many errors will not be exposed, and you need to manually open the console to view;
  • Did the code forget to import it? Sometimes after splitting multiple files, you may forget to import;
  • Is the logic wrong? The best way is to debug, which is the fastest way to find problems;
  • version conflict

Here I will focus on the last version conflict. This can even be said to be some bugs in vscode itself. It is often found that the code does not take effect inexplicably, and it is wrong to debug it. Later, it is found that the version we are developing is not running at all, especially When your plug-in has been released to the app market and installed, press F5 to run it locally. In theory, the debug operation will overwrite the installed one, but sometimes exceptions will occur, so just in case, When this happens, you can uninstall the installed one first.

Another problem is that sometimes the newer version is installed, but the old one is running. When you open the extension directory, you will find many co-existing plug-ins with different versions of the same name, or you may first install a version through vsix, and then Install another one from the application market. In short, the best way to solve this kind of problem is to uninstall it first and then install it. It is really impossible to manually delete it from the plugin directory!

open a file

Open the file is vscode.window.showTextDocumentnot vscode.workspace.openTextDocument, this is easy to get wrong according to the literal meaning, it turns out that foreigners also have inaccurate names sometimes, haha.

  • vscode.workspace.openTextDocumentJust loads the document and returns an TextDocumentobject, but doesn't open it in vscode;
  • vscode.window.showTextDocumentIt is to open a document in vscode;

actually:

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

Equivalent to:

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

Obtaining the project root directory

I have been trampled by this problem many times, so I will introduce all the highlights.

Some people's vscode workspace is like this, and each project is dragged in individually one by one:

352797-20181016093050606-1105831560.png

Some people directly open the parent folder where the code is stored by opening the folder:

352797-20181016093107878-964654349.png

But if you click 将工作区另存为to save the workspace at this point, it will look like this (note the change in the icon):

352797-20181016093116500-2050472646.png

Therefore, even if you get the full path of a file, it is not easy to get the project path of the file, because you don't know whether the folder name in the workspace is your project name or the name of the parent folder where the project is stored.

A known:

  • There used to be one vscode.workspace.rootPathin vscode. Since vscode later supports the multipleRoot mode, this field has become obsolete.
  • vscode.workspace.workspaceFoldersYou can get an array of all root folders of the current workspace;

I wrote a simple and crude way to get the project directory before:

/**
 * 获取当前所在工程根目录,有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;
},

The premise for this method to take effect is that if the workspace is stored in the first method, the number of projects must be greater than or equal to 2, but this method of judgment will certainly be inaccurate.

Later, it was changed to another way. Considering that the project that the work comes into contact with will have package.jsonfiles in the root directory whether it is on the node side or the front end, so it can only be judged according to which folder has this file.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324064728&siteId=291194637