共计 14720 个字符,预计需要花费 37 分钟才能阅读完成。
<!– START doctoc generated TOC please keep comment here to allow auto update –>
<!– DON’T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE –>
Table of Contents generated with DocToc
-
前端工程化 -VSCode 插件集成脚手架和组件库
- 前言
- VSCode 插件能做什么
-
VSCode 可扩大能力
- 基于 Electron 能力
- 可扩大能力
- 扩大工作台
- 扩大编辑器
- 限度
-
开发插件
- 初始化我的项目
- 集成 Webview
- 提供 Webview 内容
- Webview 和 VSCode 通信
-
国际化
- 配置项国际化
- VScode 代码国际化
- Webview 代码国际化
-
VSCode 插件集成基建
- AppWorks
- FAW 应用成果
- FAW 整体架构
-
FAW 新建我的项目
- 外围流程
- 外围代码实现
-
FAW 新建物料
- 外围流程
- 外围代码实现
- FAW 新建组件
- 小结
-
常见插件实现原理
- JSSnippet
- WordCount
- TODOTree
- Vetur
- 总结
- 援用
<!– END doctoc generated TOC please keep comment here to allow auto update –>
前端工程化 -VSCode 插件集成脚手架和组件库
前言
转载自搜狐 - 前端工程化 -VSCode 插件集成脚手架和组件库
<!– VSCode
是微软出的一款轻量级代码编辑器,收费而且功能强大,对 JavaScript
和NodeJs
反对十分敌对。并且提供插件机制,VSCode
很多弱小性能都是基于插件实现,比方代码格式化、代码智能补全等。–>
咱们程序员每天的产出大部分都是在 IDE
中实现,大家在日常开发过程中,多多少少会有些本人的非凡定制需要去晋升开发效率,比方写 shell
脚本、浏览器插件等,在 Visual Studio Code (VSCode)
中咱们也能开发一些插件去满足日常工作须要。
比方当初业务要新开发一个我的项目,设计稿格调和之前零碎相似。那我第一想法必定是去拷贝已有我的项目的代码(或者应用组内形象的模板),而后稍作批改满足以后需要。但如果是新同学往往须要经验 征询已有我的项目 / 模板相干人员 -> 开明各种权限 -> 复用局部代码并做个性化批改 -> 借助组件库、工具库进入业务性能开发,这个过程有肯定沟通和工夫老本。
所以我冀望能有一个更直观的形式让新同学理解组内有哪些基建并投入使用,比方能间接在 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
文件
- 例如:丑化预览
限度
于此同时,也存在一些限度,比方插件不能访 问VSCode
UI 的 DOM
节点(如果强行改变,VSCode 会提醒本身损坏)
开发插件
首先对 VSCode
插件能力有个大略意识,而后从 HelloWorld 初始化我的项目
去入门,再去集成Webview
。
因为 VSCode
自身是应用 Electron
开发的,且 Electron
是基于 Chromium
,渲染过程是应用Web
页面作为 UI 显示。那在 VSCode
中也能集成webview
。
初始化我的项目
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
集成umijs
oricejs
,上面我的项目将以 ice
为例
-
配置
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
中进行注册事件回调
- 配置
src/extension.ts
创立webview
的具体逻辑
- 注册命令
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
解决,也将处理结果传给回调函数。
在 options
中提供以后页面须要应用的所有服务 services
的定义,而后再接管到调用事件时,通过 const api = services && services[service] && services[service][method]
获取到具体的办法,并将参数进行传递,肯定水平去抹平 API
的差别,缩小反复代码量。
国际化
VSCode
的国际化次要有三局部组成
配置项
国际化VScode
代码国际化Webview
代码国际化
配置项国际化
咱们能够在 package.json
中配置 VSCode
的配置项,这些配置项的国际化是约定在 package.nls.json
和package.nls.zh-cn.json
这些文件中。
比方能够在 package.nls.json
中配置插件英文名称
{"projectCreator.create-project.commands.start.title": "Select Scaffold to Create Application"}
在 package.nls.zh-cn.json
中配置插件中文名称
{"projectCreator.create-project.commands.start.title": "抉择模板创立利用"}
而后在 package.json
中应用
"contributes": {
"commands": [
{
"command": "project-creator.create-project.start",
"title": "%projectCreator.create-project.commands.start.title%"
}
]
}
VScode 代码国际化
国际化的解决思路都一样
在代码中进行注册,并且能够通过 vscode.env.language
获取 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 代码国际化
在 Webview
中咱们采纳 icejs
搭建我的项目,那就能够应用 react-intl
来配置国际化。
而后在代码中进行应用
VSCode 插件集成基建
前端同学在开发过程中个别会经验但不限如下过程
- 开发筹备阶段:需要评审,查阅内部或组内知识库、开发标准
- 编码 & 联调阶段:按需要场景依据内部或组内脚手架、组件库、工具库 … 进行编码调试
- 调式优化阶段:数据埋点、性能优化、自动化测试 …
- 构建部署阶段 :大部分企业都有自研的
devops
解决方案 - 上线后数据采集 & 分析阶段:进行性能监控、报警、数据分析 …
- 技术积淀:对上述过程进行复盘、总结、形象,进入下一轮需要开发
当咱们进入一个新团队时,往往冀望能对团队外部的 前端研发全链路 有一个根本意识,进而能够疾速进入开发或投身到感兴趣的技术建设。
当咱们开发一个新我的项目时,往往冀望能参考老我的项目看是否能复用局部,进而缩小不必要的重复性工作。
基于下面章节对 VSCode
插件所提供的能力介绍,咱们齐全能够将 前端研发全链路
的基建集成到咱们日常编码 IDE
中,并且提供可视化的操作界面,让咱们能安心在 IDE
中进行开发调试,从肯定水平缩小咱们开发过程 到处检索 而分心低效的问题。
AppWorks
AppWorks 是一款基于 VSCode
插件的前端研发工具集,通过 GUI
操作、物料组装、代码辅助等性能让前端开发更加简略。
不过因为上面几个起因,咱们决定基于 AppWorks
做个性化革新以便满足部门外部应用。
- 他对
icejs
、Rax
类型我的项目反对敌对,但因为咱们部门中后盾我的项目技术选型为umijs
,在应用AppWorks
时面板内容显得有点冗余。 - 并且咱们我的项目应用 微前端 架构,在
slave
我的项目中不少配置是冀望在初始化模板时就主动配置好。 -
物料 方面咱们有本人一套组件库并且放在公有
npm
,自定义物料的形式也冀望能保留咱们以后发包构造- 物料:分为组件(component)、区块(block)和我的项目(scaffold)三种类型
基于上述思考,咱们做了二次开发并产出了FAW,上面将从应用成果去揭秘他的外围逻辑实现。
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 实现,开始进入代码编写
外围代码实现
其中 第 2 步 定义 模板物料 的构造,而后在配置平台保护一个 json
寄存所有模板
在 第 3 步 中抉择具体模板后拉取所有版本,次要借助 Gitlab
提供的凋谢能力 https://docs.gitlab.com/ee/api/api_resources.html
在 第 4 步 中抉择具体版本后,拉取对应代码,并判断是否存在 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
// 模板 👉
export default defineConfig({
title: '<%=repoNameZh%>',
manifest: {basePath: '/<%=repoNameEnCamel%>/',},
base: '/<%=repoNameEnCamel%>/',
outputPath,
publicPath: '/<%=repoNameEnCamel%>/',
mountElementId: '<%=repoNameEnCamel%>',
qiankun: {slave: {},
},
});
// 渲染后 👇
export default defineConfig({
title: '智能话机',
manifest: {basePath: '/smartPhone/',},
base: '/smartPhone/',
outputPath,
publicPath: '/smartPhone/',
mountElementId: 'smartPhone',
qiankun: {slave: {},
},
});
在 第 5 步 中进行拷贝和批改插入
最初 我的项目生成胜利后在窗口中关上新生成的我的项目
FAW 新建物料
- 1 通过命令
FocusWorks: Generate Page by Blocks
唤起新建页面
的页面 - 2 在面板右侧增加组件,能够在左侧进行拖拽布局
- 3 点击
生成页面
并输出页面名称和路由配置 - 4 点击实现后生成页面
外围流程
- 0 上面示例为在
umi
类型我的项目中新增一个列表页
- 1 命令行唤起
webview
页面 - 2 判断当前工作区的我的项目类型,而后从
配置核心
拉取所有“组件”列表 - 2.1 须要保护多套组件库并提供
demo
示例 - 2.2 先从依赖项中判断是否有
umi
,没有再判断是否有React
,没有再判断是否有Vue
- 3 增加组件后借助
react-sortable-hoc
反对拖拽布局 - 3.1 只反对纵向排列,因为组件粒度都较大,横向不好布局
- 4 填写页面名称(PageName)和路由配置(pageName)
- 5 从
npm
中下载具体组件tgz
到本地长期目录并解压 - 5.1 而后将
src/demo
内容拷贝到第 4 步
中所填写的页面地址的components
目录下 - 5.2 并在
PageName/index.tsx
中插入援用组件的代码 - 6 判断是否须要解决路由配置
- 6.1 如果没获取到
config/route.ts
文件则不须要配置路由,进入第 7 步
- 6.2 如果须要配置,则会读取
config/route.ts
文件内容,并插入一条路由配置 - 7 删除
第 5 步
中下载到长期目录的文件 - 8 实现
外围代码实现
在 第 2 步 中须要判断以后我的项目类型,好精确的获取对应的组件库列表。
页面物料 的构造如下,粒度个别较大,比方中后盾最常见的 面包屑 + 筛选项 + 操作栏 + 列表 + 分页
页面
第 3 步 应用 react-sortable-hoc
来反对组件的拖拽布局。
第 5 步 当点击实现时,生成页面
并配置路由
生成页面 的流程如下
- 5.1 将组件下载到本地
src/pages/PageName/components/
目录下 - 5.2 筹备
src/pages/PageName/index.tsx
页面入口模板,并写入组件援用代码 - 5.3 生成
src/pages/PageName/index.tsx
文件
5.1将组件下载到本地 src/pages/PageName/components/
目录下
- 5.1.0 筹备组件库
- 5.1.1 先下载到本地长期目录
.temp-block
- 5.1.2 将组件拷贝到以后我的项目的
pages/PageName/components/
目录下 - 5.1.3 删除长期目录的文件
- 5.1.4 主动装置组件的依赖
5.1.0 筹备组件@focus/pro-concise-table
,组件 demo 寄存在@focus/pro-concise-table/src/demos/index.tsx
5.1.1先下载到本地长期目录.temp-block
。
其中获取组件压缩包地址次要应用 package-json
实现,下载 tgz
并解压内容则借助request-promise、zlib、tar
5.1.2 将组件拷贝到以后我的项目的 pages/PageName/components/
目录下。
5.1.4 主动装置组件的依赖
第 6 步 如果须要配置路由,在创立路由时须要判断以后我的项目类型 umi/react/vue
,上面的逻辑次要是解决umi
类型我的项目
创立 umi
类型我的项目路由外围逻辑次要是依据第 第 4 步 中填写的 页面名称、路由、父级页面
做解决。
- 6.1 读取我的项目
config/routes.ts
文件内容并应用@babel/parser.parse
将代码解析为AST
- 6.2 借助
@babel/traverse
遍历 第 6.1 步 的AST
判断获取所有路由配置的数组
模式 - 6.3 将新增的路由信息拼接到 第 6.2 步 的
数组
开端 - 6.4 对路由解决后从新笼罩
config/routes.ts
文件
6.1 读取我的项目 config/routes.ts
文件内容并应用 @babel/parser.parse
将代码解析为AST
6.2 借助 @babel/traverse
遍历 第 6.1 步 的AST
判断获取所有路由配置的 数组
模式
6.4 对路由解决后从新笼罩 config/routes.ts
文件,此处为对 umi
类型我的项目解决,应用 @babel/*
做代码替换演示。
FAW 新建组件
- 1 通过命令
FocusWorks: Import Component
或在编辑器右上方题目菜单栏中点击“+”唤起新建组件
的页面 - 2 将鼠标搁置在冀望新增组件的中央,点击组件的“增加”
-
3 即可插入组件信息,并主动拷贝组件 demo、装置依赖
实现的思路大部分同 FAW 新建物料,上面将重点介绍不一样的中央
- 1 如果以后有激活的文件,则在右侧唤起
webview
- 2 能够在
contributes.menus.editor/title
中扩大编辑器题目菜单栏 - 3 在鼠标光标处插入组件代码
1如果以后有激活的文件,则在右侧唤起webview
2能够在 contributes.menus.editor/title
中扩大编辑器题目菜单栏
只在 jsx
文件中提供 新建组件
的性能
3在鼠标光标处插入组件信息
小结
此章节介绍了咱们部门以现有“智慧案场业务的微前端架构场景”(可插拔式的数据中台可能会接入若干子产品)为出发点,在此开发过程中前端组所高频应用和继续迭代的脚手架和组件库,为了让各个子产品线能疾速和低成本接入,咱们尝试在 IDE 中将他们进行了集成和实现。
目前这一套 IDE 插件撑持了咱们 15+ 个“宝宝”子产品 的我的项目初始化工作,为各个业务线同学接入后期防止了大量繁琐的配置操作;也为大家开发过程提供可扩大能力:在应用公共页面和组件时能够拿来即用,也能够疾速封装各自高频物料供所有人抉择应用;
FAW 的定位次要是 后期老同学奉献模板和组件,对新同学特地敌对,过程中新老同学一起共建,服务于整个团队。
于此同时咱们捆绑了组内都在应用的其余提效插件供大家一键装置,防止新同学和组外在开发过程体现不统一的问题。
常见插件实现原理
上面简略介绍几个 FAW
中捆绑的插件的外围实现原理。
JSSnippet
作用:实现 JavaScript/React/TypeScript
代码主动补全
仓库:VS Code ES7+ React/Redux/React-Native/JS snippets
外围实现:
// package.json
{
"contributes": {
"snippets": [
{
"language": "javascript",
"path": "./snippets/snippets.code-snippets"
}
]
}
}
// ./snippets/snippets.code-snippets.json
{
"typescriptReactFunctionalComponent": {
"key": "typescriptReactFunctionalComponent",
"prefix": "tsrfc",
"body": [
"import React from'react'","",
"type Props = {}",
"","export default function ${1:${TM_FILENAME_BASE}}({}: Props) {"," return ("," <div>${1:first}</div>"," )","}"],"description":"Creates a React Functional Component with ES7 module system and TypeScript interface","scope":"typescript,typescriptreact,javascript,javascriptreact"
},
}
WordCount
作用:实时计算 .md
文件中字数
仓库:https://github.com/microsoft/vscode-wordcount
外围实现:
import {window} from 'vscode'
const statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left);
let doc = window.activeTextEditor.document;
// 只解决 `.md` 文件
if (doc.languageId === 'markdown') {let docContent = doc.getText();
// 将边界的空格删掉
docContent = docContent.replace(/(< ([^>]+)<)/g, '').replace(/\s+/g,' ');
docContent = docContent.replace(/^\s\s*/, '').replace(/\s\s*$/,'');
let wordCount = 0;
if (docContent !== '') {
// 获取单词数
wordCount = docContent.split(' ').length;
}
// 将以后文件的字数在左下角状态栏展现,其中 `$(pencil)` 是 vscode 提供的图标
statusBarItem.text = `$(pencil) ${wordCount} Words`;
// 在状态栏展现单词数
statusBarItem.show();}
TODOTree
作用:实现特定文本高亮
地址:https://github.com/Gruntfuggly/todo-tree
外围代码:
// 下方为伪代码
const documentHighlights = {}
const tag = 'todo'
// 1、应用正则全局匹配 todo、fixme、hack... 的坐标地位
// const regex = (//|#|<!--|;|/\\*|^|^[ \\t]*(-|\\d+.))\\s*($TAGS)/
while(( match = regex.exec( editor.document.getText() ) ) !== null ) {const range = new vscode.Range( startPos, endPos)
const decorationOptions = {
range,
backgroundColor: 'green',
color: '#fff'
}
// 2、通过 createTextEditorDecorationType 构建文本装璜类型对象
documentHighlights[tag] = vscode.window.createTextEditorDecorationType(decorationOptions)
}
// 3、在编辑器中设置文本装璜定义
editor.setDecorations(decoration, documentHighlights[ tag] )
// 4、`TODO` 文本高亮展现
// TODO
// 5、还能够扩大到色号字符处展现对应色值
Vetur
作用:实现 .vue
文件的词法高亮、代码补全、错误诊断、格式化
仓库:https://github.com/vuejs/vetur
LSP 文档:https://www.bookstack.cn/read/VS-Code-Extension-Doc-ZH/docs-l…
总结
上述外围代码寄存在 https://github.com/careteenL/faw
咱们首先理解了 vscode 提供哪些能力,咱们能做什么。
再通过官网脚手架初始化一个我的项目去入门,因为 vscode 基于 electron,基于 chrome,咱们能在 vscode 中集成 webview 去丰盛页面。
然而因为在 webview 中不能调用接口,所以须要在 vscode 端进行接口调用,所以须要 vscode 和 webview 通信。
国际化的配置思路都相似。
而后基于公司外部的现状:咱们冀望有一个 GUI 去实现创立我的项目和新增页面组件。去二次开发一款 vscode 插件。
架构设计时依据性能将插件拆分,提供一个主入口,装置时主动装置相干插件。主入口还能够捆绑其余组内高频应用的插件。
而后将页面交互都交由 webview 去做,外围逻辑(调接口、渲染我的项目、新建文件)还是交由 vscode 做;并采纳 lerna 将专用逻辑进行封装,不便各个插件调用;数据局部存储在公司外部 gitlab 和公有 npm,而后采纳配置平台治理数据大 json。
新建我的项目时和脚手架 @focus/cli 的逻辑基本一致,区别在于对读取提供的 ask-for-vscode.js
文件内容时采纳 fs.readFile + new Function(code)
的形式进行 hack。
新建页面时须要保护一套组件库,并存放在公有 npm 中,而后依据用户抉择去下载对应组件的 tgz
压缩包,而后进行解析,再拷贝到以后我的项目的 pages/components
目录下,最初还需在 routes.ts
文件中插入一条路由。
在代码指定地位新增组件时,和新建页面思路相似,区别在于须要获取以后鼠标的光标地位。
工欲善其事,必先利其器。咱们能够在 IDE 中去集成组内的基建,能让开发同学更直观的理解和应用;并将重复性的工作形象封装进 VSCode 插件,撑持咱们 15+ 个“宝宝”子产品 的我的项目接入和开发,为大家开发提效。
援用
- VSCode 官网
- VSCode 插件开发全攻略配套 demo
- 前端工程化 - 打造企业通用脚手架
- 基于 VSCode 插件的前端研发工具 AppWorks