vscode插件开发

281 阅读2分钟

背景:因为yp项目组规范要求。分支名必须是 特征/飞书id-name且commit的时候也必须带上飞书项目id,所以为了

  1. 方便开发commit,便捷复制飞书id;
  2. 方便打开项目文档。不需要特意去找对应的飞书项目,直接从编辑器打开文档

开发

  1. 创建项目 npx --package yo --package generator-code -- yo code

    • 最好选择npm管理项目。因为到时候vsce打包发布的时候只支持yarn npm
  2. 定义描述命令

    "contributes": {
        "commands": [
          {
            "command": "extention.ypLink",
            "title": "YP-LINK: Show Branch And FeishuId"
          }
        ]
      },
    
  3. 注册命令

    export function activate(context: vscode.ExtensionContext) {
      // 需要注意的是 注册命令的名称 和在 package.json得描述一致
      const disposable = vscode.commands.registerCommand("extention.yp-link", () => {
        // ...
      })
    }
    
  4. 获取分支名、飞书id等信息

获取到分支信息是否还有其他方式 求助大佬

```typescript
function getBranchName() {
  const gitExtension = vscode.extensions.getExtension("vscode.git");
  if (!gitExtension) {
    vscode.window.showErrorMessage("Git extention not found");
    return;
  }
  const gitApi = gitExtension.exports.getAPI(1);
  const repo = gitApi.repositories[0];
  const branchName = repo.state.HEAD?.name ?? "";
  return branchName;
}
const feishuId = extractFeishuId(branchName);
const extractFeishuId = (branchName: string) => {
  const reg = /.*[-|/](?<id>\d+)/gm;
  let match = reg.exec(branchName);
  const id = match?.groups?.id ?? "";
  return id;
};
```

5. Webview 展示

```typescript
const webviewPannel = vscode.window.createWebviewPanel(
  "branchAndFeishuidView",
  "Show Branch And FeishuId",
  vscode.ViewColumn.One,
  {
    enableScripts: true,
  }
);

webviewPannel.webview.html = getWebviewContent(branchName, feishuId);
```

```javascript
function getWebviewContent(branchName: string, feishuId: string) {
  return `
  <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Branch Info And FeishuId</title>
  </head>
  <body>
    <p>
      <span style="padding-right: 20px">
        <strong>Branch Name:</strong> ${branchName}</span
      >
      <button id="copyBranchName">Copy Branch Name</button>
    </p>
    <p>
      <span style="padding-right: 20px">
        <strong>FeishuId:</strong>
        <span> ${feishuId}</span>
      </span>
      <button id="copyFeishuId">Copy 飞书ID</button>
    </p>

    <p>
      <button id="openFeishuProject">打开飞书项目</button>
    </p>

    <script>
      const vscode = acquireVsCodeApi();

      const branchName = "${branchName}";
      const feishuId = "${feishuId}";

      const copyBranchNamebtn = document.querySelector("#copyBranchName");
      copyBranchNamebtn.addEventListener("click", () => {
        copyText(branchName);
      });

      const copyFeishuIdSpan = document.querySelector("#copyFeishuId");
      copyFeishuIdSpan.addEventListener("click", () => {
        if (!feishuId) {
          return;
        }
        copyText(feishuId);
      });

      function copyText(text) {
        navigator.clipboard.writeText(text).then(() => {
          vscode.postMessage({
            command: "showMessage",
            text: text + "copyied to cliboard",
          });
        });
      }

      const openFeishuProjectBtn = document.querySelector("#openFeishuProject");
      openFeishuProjectBtn.addEventListener("click", () => {
        try {
          if (!feishuId) {
            return;
          }
          vscode.postMessage({
            command: "openBrowser",
            url: "https://project.feishu.cn/yupao/story/detail/" + feishuId,
          });
        } catch (error) {
          vscode.postMessage({
            command: "showErrorMessage",
            text: error?.message || "打开浏览器错误",
          });
        }
      });
    </script>
  </body>
</html>
  `;
}
```

6. 插件和webview通信。 值得注意的是,在html文档里需通过 acquireVsCodeApi 方法调用获取到通信的桥梁

```typescript
webviewPannel.webview.onDidReceiveMessage((message: IMessage) => {
  switch (message.command) {
    case "showMessage":
      vscode.window.showInformationMessage(message.text ?? "");
      break;
    case "showErrorMessage":
      vscode.window.showErrorMessage(message.text ?? "");
      break;
    case "openBrowser":
      if (!message.url) return;
      const url = vscode.Uri.parse(message.url);
      vscode.env.openExternal(url);
      break;
    default:
      break;
  }
});

// webview 
const vscode = acquireVsCodeApi();
vscode.postMessage({...})
```

打包发布

传送门

npm install -g @vscode/vsce
vsce package

打包后可以选择发布到应用市场 或者 只在组内分享的话可以将xxx.vsix文件分享。在vscode 拓展里。菜单选择install from vsix

总结

为了减少commit携带飞书id,寻找飞书项目的心智负担,简单开发了这个vscode插件。vscode插件功能很强大,还有很地方值得学习。todo🐶

仓库地址: yp-link

参考文献

  1. vscode plugin官方文档
  2. How to access the api for git in visual studio code