日期:
来源:全栈修仙之路收集编辑:博点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
生成的webview
web
目录初始化项目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-cre
ator.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
端打的tag
4. 选择“具体版本”后,判断当前模板是否提供 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
// 模板