日期:
来源:全栈修仙之路收集编辑:博点Careteen
目录
VSCode插件能做什么? VSCode可扩展能力有哪些? 如何开发一个VSCode插件? VSCode插件如何集成基建的脚手架和组件库?(FAW保姆级教程) 前端常见插件的实现原理分析?
前言
IDE中完成,大家在日常开发过程中,多多少少会有些自己的特殊定制需求去提升开发效率,比如写shell脚本、浏览器插件等,在Visual Studio Code (VSCode)中我们也能开发一些插件去满足日常工作需要。VSCode中罗列当前的模板项目,预览后选择特定模板进行项目初始化,并且将一些个性化基础配置通过表单形式进行填写并渲染,避免遗漏。而且在开发过程能在VSCode中直观的展示当前有哪些组件和工具函数可以使用,然后通过点点点操作实现组件的添加和快速使用。VSCode插件能做什么?如何开发一款 VSCode插件?VSCode中如何嵌入webview?VSCode中如何配置国际化?VSCode插件中如何新建项目、新建页面、组件...?
VSCode插件能做什么
VSCode 插件可分为下面几大类:语言类插件 语法高亮(Vetur) 代码自动补全(TabNine) 代码片段(JS JSX Snippets) 工具类插件 可视化搭建页面(面向开发者的低代码)(AppWorks) 时间管理(WakaTime) Git管理(Git Graph) TODO(TODO Tree)
娱乐类插件 听音乐(VSC Netease Music) 炒股(韭菜盒子) 玩游戏(小霸王)
VSCode可扩展能力
本章大部分内容在官网中已有说明,此次做简单了解
VSCode 提供哪些能力去实现上一章所提到的效果?基于Electron能力
VSCode本身是使用Electron开发的,那他也支持对应的能力。支持读取本地文件 支持发送接受跨域请求 支持创建本地服务器 持久化存储本地数据
可扩展能力
使用颜色或文件图标主题更改 VSCode外观 在 UI中添加自定义组件和视图 创建 webview以显示使用 HTML/CSS/JS构建的自定义网页 支持一种新的编程语言 支持调试特定运行时
扩展工作台
VSCode提供了各种 API,允许您将自己的组件添加到工作台。活动栏(Tree View Container): Azure应用服务扩展添加了一个视图容器侧边栏(Tree View):内置的 NPM扩展在Explorer视图中添加了一个树视图编辑器组(Webview):内置的 Markdown扩展在编辑器组中的其他编辑器旁边添加了一个 Webview状态栏(Status Bar): VSCodeVim扩展在状态栏中添加了一个状态栏项
扩展编辑器
基于正则编辑页面中的内容 例如:删掉当前页面所有注释或 log自定义跳转、自动补全、悬浮提示 例如:输入 rfc自动补全代码 对特定后缀名文件的解析和编辑 例如:借助插件 vetur解析 .vue文件 增强 VSCode内置的 MD预览和 Git工具 例如:美化预览 .md文件
限制
开发插件
初始化项目
npm i -g yo generator-code
yo code
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? HelloWorld
## Press <Enter> to choose default for all options below ###
? What's the identifier of your extension? helloworld
? What's the description of your extension? LEAVE BLANK
? Initialize a git repository? Yes
? Bundle the source code with webpack? No
? Which package manager to use? npm
? Do you want to open the new folder with Visual Studio Code? Open with `code`
.
├── package.json # 插件配置
├── src
│ ├── extension.ts # 入口文件
├── tsconfig.json
package.json关键内容如下:{
// 扩展的激活事件
"activationEvents": [
"onCommand:extension.sayHello"
],
// 入口文件
"main": "./src/extension",
// 贡献点,vscode插件大部分功能配置都在这里
"contributes": {
"commands": [
{
"command": "extension.sayHello",
"title": "Hello World"
}
]
}
}
src/extension.ts关键内容如下:const vscode = require('vscode');
// 插件被激活时触发,所有代码总入口
exports.activate = function(context) {
// 注册命令 与`package.json`中`contributes.commands`
context.subscriptions.push(vscode.commands.registerCommand('extension.sayHello', function () {
vscode.window.showInformationMessage('Hello World!');
}));
};
// 插件被释放时触发
exports.deactivate = function() {};
F5 即可打开新的窗口在命令面板中(⌘⇧P)运行 Hello World 命令进行调试插件:集成Webview
VSCode集成通过ice生成的webviewweb目录初始化项目mkdir web
cd web
yarn create ice
# or
yarn create @umijs/umi-app
package.json注册激活事件{
"activationEvents": ["onCommand:project-creator.create-project.start"],
"contributes": {
"commands": {
"command": "project-creator.create-project.start",
"title": "创建项目webview"
}
}
}
activationEvents字段值为数组,通过onCommand注册激活事件project-creator.create-project.start,而project-creator.create-project.start将在contributes.commands中定义contributes字段可以配置扩展VSCode各种能力,比如commands命令、configuration配置...commands中的command将在src/extension.ts中进行注册事件回调
注册命令 project-creator.create-project.start创建 webview面板 projectCreatorWebviewPanel如果有,则直接展示 如果没有,则新建 配置基本配置 标题 启用 JavaScript脚本 隐藏时保留上下文 图标 设置 webview 面板内容 提供 webview和 vscode交互
VSCode中的Webview本质就是一个iframe,所以是可以在其中执行脚本,但是VSCode默认禁用JavaScript,所以需要配置enableScripts=true开启此功能。提供Webview内容
getHtmlForWebview获取 webview 的内容。icejs进行构建项目,yarn build后的目录结构为index.html、css/index.css、js/index.js,如果开启MPA,则还有vendor.css/js。如果使用其他框架比如 umijs,则采取不同的处理方式即可。
getNonce生成一个随机数,设置到script的 nonce属性,作用是在加密通信中使用一次随机数避免重复攻击,保证不同的消息与该秘钥加密的秘钥流不同。此代码拷贝自VSCode提供的官网示例。Webview和VSCode通信
webview中通过调接口获取数据,然后渲染页面。但是在vscode webview中是不允许发送ajax请求,所有请求都是跨域(因为webview本身没有host),所以需要在VScode中进行真实的接口请求。Webview端使用vscode.postMessage,然后在VScode中使用webview.onDidReceiveMessage接收到消息后做相应处理。connectService和callService进行统一注册和调用。可以在 VSCode端创建 Webview时绑定 connectService,在其中监听 webview接收到的消息,然后调用 VSCode中 api能力,将执行结果返回给 Webview端 在 Webview中调用 callService,然后将事件和参数传递给 connectService处理,也将处理结果传给回调函数。
国际化
VSCode的国际化主要有三部分组成:配置项国际化 VScode代码国际化 Webview代码国际化
配置项国际化
{
"projectCreator.create-project.commands.start.title": "Select Scaffold to Create Application"
}
{
"projectCreator.create-project.commands.start.title": "选择模板创建应用"
}
"contributes": {
"commands": [
{
"command": "project-creator.create-project.start",
"title": "%projectCreator.create-project.commands.start.title%"
}
]
}
VScode代码国际化
import * as vscode from 'vscode';
import I18nService from './i18n';
import * as zhCNTextMap from './locales/zh-CN.json'; // { "webViewTitle": "Create Project" }
import * as enUSTextMap from './locales/en-US.json'; // { "webViewTitle": "创建项目" }
// 注册语言表
const i18n = new I18nService();
i18n.registry('zh-cn', zhCNTextMap);
i18n.registry('en', enUSTextMap);
// 设置使用的语言
i18n.setLocal(vscode.env.language);
export default i18n;
projectCreatorWebviewPanel = vscode.window.createWebviewPanel(
'project-creator', // webview 标识,只供内部使用
i18n.format('webViewTitle'), // 标题
vscode.ViewColumn.One, // 新开一个编辑器视图
{
enableScripts: true, // 启用 JavaScript 脚本
retainContextWhenHidden: true, // 隐藏时保留上下文
},
);
Webview代码国际化
然后在代码中进行使用:
VSCode插件集成基建
开发准备阶段 : 需求评审,查阅外部或组内知识库、开发规范 编码&联调阶段: 按需求场景根据外部或组内脚手架、组件库、工具库...进行编码调试 调式优化阶段 : 数据埋点、性能优化、自动化测试... 构建部署阶段:大部分企业都有自研的 devops解决方案上线后数据采集&分析阶段: 进行性能监控、报警、数据分析... 技术沉淀: 对上述过程进行复盘、总结、抽象,进入下一轮需求开发
VSCode插件所提供的能力介绍,我们完全可以将前端研发全链路的基建集成到我们日常编码IDE中,并且提供可视化的操作界面,让我们能安心在IDE中进行开发调试,从一定程度减少我们开发过程到处检索而分心低效的问题。AppWorks
VSCode插件的前端研发工具集,通过 GUI 操作、物料组装、代码辅助等功能让前端开发更加简单。AppWorks做个性化改造以便满足部门内部使用。他对 icejs、Rax类型项目支持友好,但由于我们部门中后台项目技术选型为umijs,在使用AppWorks时面板内容显得有点冗余。并且我们项目使用 微前端 架构,在 slave项目中不少配置是期望在初始化模板时就自动配置好。物料 方面我们有自己一套组件库并且放在私有 npm,自定义物料的方式也期望能保留我们当前发包结构物料: 分为组件(component)、区块(block)和项目(scaffold)三种类型
FAW使用效果
微前端子应用的场景1. 通过点击侧边栏激活创建项目流程 2. 选择具体模板后点击下一步 3. 输入项目名称、模板版本 4. 如果模板提供 ask-for-vscode.js文件,则根据配置生成表单主要是配置 publicPath、basePath、mountElementId、id...5. 表单填写完毕后点击完成 6. 生成项目后在当前窗口打开新项目,即可进入开发
FAW整体架构
模板选择、填写配置这些交互功能放在展示层webview中实现,而将获取模板、拷贝模板并渲染这些功能交由业务层VSCode实现。AppWorks中“捆绑”组内高频使用插件,实现安装一个插件时可以安装一系列插件。公共配置项、国际化、创建项目和创建物料的核心逻辑...放入packages中使用lerna做管理并在插件中使用。配置平台中做统一配置;项目模板存放在Gitlab做版本管理;组件库放在私有npm做管理。FAW新建项目
focus create projectName核心流程核心流程
1. 点击“创建应用”,唤起 webview页面2. 从 配置中心拉取所有“项目模板”列表3. 选择“具体模板”后,拉取所有版本(版本默认约定为在 Gitlab端打的tag4. 选择“具体版本”后,判断当前模板是否提供 ask-for-vscode.js文件4.1 如果没提供则对本模板本版本做本地缓存,方便下次使用。则进入第6步 4.2 如果提供则根据配置项渲染为表单供开发者填写 配置项一般为 publicPath、basePath、mountElementId、id...5. 通过 ncp把代码拷贝到本地临时目录,然后根据 4.2 填写的内容渲染变量在ejs模板,最后通过metalsmith遍历所有文件做插入修改6. 打开新窗口并启动当前项目 7. 完成,开始进入代码编写 核心代码实现
核心代码实现
json存放所有模板。Gitlab提供的开放能力 https://docs.gitlab.com/ee/api/api_resources.html。ask-for-vscode.js文件并解析其内容:require需要以require(/Users/${filename}.js)的形式导入绝对路径+变量,然而我们模板的名字以及配置都名为变量,故获取不到。// 此方式可行 ✅
const code = require('/Users/careteen/Desktop/admin-umi-template/ask-for-vscode.js')
// 此方式不可行 ❌
const templateName = 'admin-umi-template'
const configName = 'ask-for-vscode'
const args = require(`/Users/careteen/Desktop/${templateName}/${configName}.js`)
readFileSync和new Function(code)()的方式获取js文件内容。其中内容如下:// 需要根据用户填写修改的字段
const requiredPrompts = [
{
type: 'input',
name: 'repoNameEn',
message: 'please input repo English Name ? (e.g. `smart-phone`.focus.cn)',
},
{
type: 'input',
name: 'repoNameEnCamel',
message: 'please input repo English Camel Name ?(e.g. smart-case.focus.cn/`smartPhone`)',
},
{
type: 'input',
name: 'repoNameZh',
message: 'please input repo Chinese Name ?(e.g. `智能话机`)',
},
];
return {
requiredPrompts,
};
ejs模板,比如配置文件config/config.ts// 模板