自定义一个vscode插件

55 阅读2分钟

创建一个vscode 插件

文档

安装环境

安装一个脚手架工具yeoman

npm install -g yo

安装 vscode 扩展 的yeoman生成器

npm install -g generator-code

创建项目

yo code myExtensionProject

项目结构

├── CHANGELOG.md
├── LICENSE
├── README.md
├── out
│   ├── extension.js
│   ├── extension.js.map
│   └── test
│       ├── runTest.js
│       ├── runTest.js.map
│       └── suite
│           ├── extension.test.js
│           ├── extension.test.js.map
│           ├── index.js
│           └── index.js.map
├── package-lock.json
├── package.json
├── src
│   ├── extension.ts
│   └── test
│       ├── runTest.ts
│       └── suite
│           ├── extension.test.ts
│           └── index.ts
└── tsconfig.json

编码

extension.ts 中实现核心逻辑

import path = require('path');
import * as vscode from 'vscode';
import fs = require('fs');

export function activate(context: vscode.ExtensionContext) {
	let disposable = vscode.commands.registerCommand('rich.openRoot', async (url) => {
		const pageName = await vscode.window.showInputBox({
			password: false, // 输入内容是否是密码
			placeHolder: '模块名称', // 在输入框内的提示信息
			prompt: '请输入创建页面模块名称', // 在输入框下方的提示信息
			// validateInput:function(text){return text;} // 对输入内容进行验证并返回
		}) || '';

		if (!pageName) {
			vscode.window.showErrorMessage('页面模块名称不能为空');
			return;
		}

		// 当前工作目录
		const currentWorkDir = (vscode.workspace.workspaceFolders|| [])[0].uri.path;
		const templatePath = path.resolve(currentWorkDir, 'mpa.template.js');

		// 如果工作根目录下没有map.template.js文件提示报错
		try {
			await fs.promises.stat(templatePath);
		} catch (err) {
			vscode.window.showErrorMessage('The template file "mpa.template.js" cannot be empty');
			return;
		}

		const filePath = path.normalize(path.resolve(url.path, pageName));
		if (!fs.existsSync(filePath)) {
			fs.mkdirSync(filePath);
		}

		// 获取当前工作目录下mpa.tempalte.js中的模板配置
		const config = require(templatePath);

		const templates = config.render(pageName);
		Object.keys(templates).forEach(fileName => {
			fs.writeFile(filePath + `/${fileName}`, templates[fileName], () => {});
		});
	});

	context.subscriptions.push(disposable);
}

export function deactivate() {}

package.json 中配置对应的信息

{
    // 插件名称,应全部小写不能有空格
    "name": "rich-mutil-page",
    // 应用市场名称,支持中文
    "displayName": "mutil-page",
    // 插件描述
    "description": "用于mpa项目中,快速创建入口",
    // 关键字,用于应用市场搜索
    "keywords": ["vscode", "mpa"],
    // 版本
    "version": "1.0.0",
    // 发布者,
    "publisher": "rich",
    // 表示插件最低支持的vscode版本
    "engines": {
        "vscode": "^1.73.0"
    },
    // 插件应用市场分类,可选值:[Programming Languages, Snippets, Linters, Themes, Debuggers, Formatters, Keymaps, SCM Providers, Other, Extension Packs, Language Packs]
    "categories": ["Other"],
    // 主入口 
    "main": "./out/extension.js",
    // 插件图标,至少128*128
    "icon": "",
    // 扩展的激活事件数组
    "activationEvents": []

}

activationEvents

插件在 vscode 中默认是没有激活的,通过 activationEvents 进行配置

1、onLanguage

当打开特定语言的文件时,插件被激活

2、onCommand

当调用命令时,插件被激活

  • onDebug
  • workspaceContains
  • onFileSystem
  • onView
  • onUri
  • onWebviewPannel
  • onCustomEditor
  • onStartupFinished

contributes

1、commands 命令

提供了一个由 commandstitle 字段组成的条目,用于在 命令面板(⇧⌘P)中调用。你同时也可以选择添加一个 category 字符串,此字符串会用作命令的前缀,同时在命令面板展开的时候方便进行命令的分组。

当一个命令被调用的时候(无论是通过按键还是 命令面板),VS Code 将触发一个 activationEvent onCommand:${command}

Example

{
    "contributes": {
        "commands": [{
            "command": "rich.openRoot",
            "title": "创建模块",
            "category": "rich"
        }]
    }
}

image.png

2、menus 菜单

菜单项定义了选择时应该调用的命令以及不同情况下命令的的显示方式。后者使用 when 子句,并结合 子句上下文 通过按键绑定来定义的。

目前拓展的开发者能够修改这些部分:

  • 全局的命令面板 - commandPalette
  • 资源管理器环境菜单 - explorer/context
  • 编辑器环境菜单 - editor/context
  • 编辑器的标题菜单栏 - editor/title
  • 调试调用堆栈的上下文菜单 - debug/callstack/context

发布

本地打包

安装vsce

npm i vsce -g

发布到应用市场

vsce login rich

此时会让你输入 person access token。如果不清楚怎么获取,看下面章节

vsce publish

获取 person access token

第一步:打开 vscode extentions 地址:marketplace.visualstudio.com/vscode

第二步:进入你的账号

image.png

第三步:进入你创建的组织

image.png

第四步:在组织看板里面获取Personal access token

image.png

vscode.window api

错误提示弹窗

vscode.window.showErrorMessage('页面模块名称不能为空');

image.png

输入框

const inputStr = await vscode.window.showInputBox({
    password: false,
    placeHolder: '模块名称',
    prompt: '请输入创建页面模块名称',
})

image.png