如何在 10 分钟内完成一款 vscode 扩展开发

6,240 阅读2分钟

前言

vscode 是一款深受广大开发者喜爱的代码编辑器,同时拥有强大而简单的扩展开发 API,让开发者可以深度定制自己的开发环境。

本文从一个真实案例出发,演示如何在 10 分钟内完成一款 vscode 扩展开发,最终上架发布。

需求背景

在日常工作中,我们经常需要将一段文本发送到手机上,或者需要在手机上打开一个网页 url。

通常的做法是使用微信/QQ 等多端同步工具。

如果可以不离开编辑器,直接将选中的文本或 url 转换为二维码,然后用手机扫一扫就可以获取,是不是方便许多?

准备工作

明确需求后,就可以准备动手开发了。

不过,开始之前请先阅读一遍官方开发文档:code.visualstudio.com/api

vscode 提供了丰富的 API 开放能力,包括:

  • 注册命令、快捷键、上下文菜单
  • 存储工作区或全局数据
  • 显示通知弹窗、进度条
  • 使用输入提示框获取用户输入
  • 打开系统提供的文件选择器
  • 等等...

扩展开发

脚手架

首先,安装 vscode 扩展开发脚手架:

npm install -g yo generator-code

接下来使用 yo 按提示完成项目的基本信息配置,并自动生成扩展框架:

$ yo code

     _-----_     ╭──────────────────────────╮
    |       |    │   Welcome to the Visual  │
    |--(o)--|    │   Studio Code Extension  │
   `---------´   │        generator!        │
    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

? What type of extension do you want to create? New Extension (JavaScript)
? What's the name of your extension? text2qrcode
? What's the identifier of your extension? text2qrcode
? What's the description of your extension? A vscode extension generates qrcode from text
? Enable JavaScript type checking in 'jsconfig.json'? Yes
? Initialize a git repository? No
? Which package manager to use? npm
......

至此,我们的 vscode 扩展基本框架就生成好了,目录结构如下:

.
├── CHANGELOG.md
├── README.md
├── extension.js
├── jsconfig.json
├── node_modules
├── package-lock.json
├── package.json
├── test
└── vsc-extension-quickstart.md

配置与依赖

接下来,修改 package.json:

{
  "name": "text2qrcode",
  "displayName": "Text2QRCode",
  "description": "generate qrcode from text",
  "version": "1.0.0",
  "publisher": "Ceelog", // 发布者 id
  "engines": {
    "vscode": "^1.30.0" 
  },
  "icon": "text2qrcode.png", // 扩展图标
  "keywords": [
    ...
  ],
  "categories": [
    "Other"
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/Ceelog/text2qrcode.git" // 扩展 Git 仓库地址
  },
  ...
  "activationEvents": [
    "onCommand:extension.text2qrcode" // 注意和扩展代码内的命令名称保持一致
  ],
  "main": "./extension.js",
  "contributes": {
    "commands": [
      {
        "command": "extension.text2qrcode", // 通过命令使用扩展
        "title": "Text2QRCode"
      }
    ],
    "menus": {
      "editor/context": [
        {
          "command": "extension.text2qrcode", // 通过菜单使用扩展
          "title": "Text2QRCode"
        }
      ]
    }
  },
  ...
  "devDependencies": {
    ...
  },
  "dependencies": {
    "q": "^1.4.1",
    "qrcode": "^1.4.4" // 扩展需要使用的依赖
  }
}

我们在自动生成的框架基础上,增加了publisher icon repository contributes.menus 以及扩展依赖 dependencies,修改了 activationEvents.onCommand 的命令名称。

由于新增了依赖,所以需要完成依赖安装:npm install

扩展代码

我们的扩展功能比较简单:

选中文本 -> 右键生成二维码 -> 展现二维码

所以,只需要在菜单上注册一个入口选项Text2QRCode,当用户点击后,vscode 会执行扩展的激活回调方法,获取当前编辑器内选中的文本(如果没有选中,则弹出对话框让用户输入),然后将文本转换为二维码图片数据,再通过 new tab 展现图片即可。

以上逻辑都在 extension.js中实现:

const vscode = require('vscode');
const Q = require('q');
const QRCode = require('qrcode');
...
// 扩展激活回调方法
function activate(context) {
  let disposable = vscode.commands.registerCommand('extension.text2qrcode', function () {
    getSelectedTextOrPrompt('Text to convert into QR code')
      .then(text => {
        if (!text) { return; }
        // 将文本转换为二维码图片
        QRCode.toDataURL(text, {errorCorrectionLevel: 'L'}, function (err, url) {
          if (!err) {
            // 在新标签页展现二维码图片
            const panel = vscode.window.createWebviewPanel(
              'Text2QRCode',
              'Text2QRCode',
              vscode.ViewColumn.One,
              {}
            );
            panel.webview.html = getPreviewHtml(url);
          } else {
            vscode.window.showErrorMessage(err.message);
          }
        });
      });
  });
  context.subscriptions.push(disposable);
}

// 展现二维码图片
function getPreviewHtml(image) {
  return `<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Text2QRCode</title>
    </head>
    <body>
    <div style="display: flex; min-height: 240px; height: 100%; width: 100%;">
        <div style="display: flex; flex: 1; flex-direction: column; justify-content: center;">
            <img src="${image}" style="align-self: center;" />
        </div>
    </div>
    </body>
    </html>`;
}

// 获取当前选中内容 或者 提示用户输入
function getSelectedTextOrPrompt(prompt) {
  const activeTextEditor = vscode.window.activeTextEditor;
  if (activeTextEditor) {
    const
      selection = activeTextEditor.selection,
      start = selection.start,
      end = selection.end;
    if (start.line !== end.line || start.character !== end.character) {
      return Q(activeTextEditor.document.getText(selection));
    }
  }
  return vscode.window.showInputBox({ prompt });
}
...

至此,我们便完成了扩展的全部开发内容。

另外,只需在相应代码行打上断点,然后按下 F5 就可以进入调试模式。

扩展运行效果:

发布上架

完成扩展开发之后,我们就可以打包发布。

首先,安装官方发布脚本:npm install -g vsce

然后执行打包脚本:

$ vsce package
...
DONE  Packaged: /mnt/g/text2qrcode.git/text2qrcode-1.0.0.vsix (323 files, 749.32KB)

现在你就可以将打包好的扩展文件text2qrcode-1.0.0.vsix发送给其他人使用了。

或者,将扩展上传到官方扩展市场:

marketplace.visualstudio.com/manage/

这样就可以在 vscode 内直接搜索安装:

结语

恭喜你,在 10 分钟内完成了一款 vscode 扩展开发,赶紧安装体验一下吧!

别忘了给你的扩展制作一个精美的图标哦 ;)

附录