<!-- 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是微软出的一款轻量级代码编辑器,收费而且功能强大,对JavaScriptNodeJs反对十分敌对。并且提供插件机制,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

  1. 创立web目录初始化我的项目

    mkdir webcd webyarn create ice# oryarn create @umijs/umi-app

集成umijsoricejs,上面我的项目将以 ice 为例

  1. 配置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中进行注册事件回调
  1. 配置src/extension.ts创立webview的具体逻辑
  • 注册命令project-creator.create-project.start
  • 创立 webview 面板projectCreatorWebviewPanel

    • 如果有,则间接展现
    • 如果没有,则新建
  • 配置根本配置

    • 题目
    • 启用JavaScript 脚本
    • 暗藏时保留上下文
    • 图标
  • 设置 webview 面板内容
  • 提供 webviewvscode 交互

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生成一个随机数,设置到scriptnonce属性,作用是在加密通信中应用一次随机数防止反复攻打,保障不同的音讯与该秘钥加密的秘钥流不同。此代码拷贝自VSCode提供的官网示例。

Webview和VSCode通信

一个很常见的场景,咱们在webview中通过调接口获取数据,而后渲染页面。然而在vscode webview中是不容许发送ajax申请,所有申请都是跨域(因为webview自身没有host),所以须要在VScode中进行实在的接口申请。

此过程则变为在Webview端应用vscode.postMessage,而后在VScode中应用webview.onDidReceiveMessage接管到音讯后做相应解决。

将交互过程封装成connectServicecallService进行对立注册和调用。

  • 能够在VSCode端创立Webview时绑定connectService,在其中监听webview接管到的音讯,而后调用VSCodeapi能力,将执行后果返回给Webview
  • Webview中调用callService,而后将事件和参数传递给connectService解决,也将处理结果传给回调函数。

options中提供以后页面须要应用的所有服务services的定义,而后再接管到调用事件时,通过const api = services && services[service] && services[service][method]获取到具体的办法,并将参数进行传递,肯定水平去抹平API的差别,缩小反复代码量。

国际化

VSCode的国际化次要有三局部组成

  • 配置项国际化
  • VScode代码国际化
  • Webview代码国际化
配置项国际化

咱们能够在package.json中配置VSCode的配置项,这些配置项的国际化是约定在package.nls.jsonpackage.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做个性化革新以便满足部门外部应用。

  • 他对icejsRax类型我的项目反对敌对,但因为咱们部门中后盾我的项目技术选型为umijs,在应用AppWorks时面板内容显得有点冗余。
  • 并且咱们我的项目应用微前端架构,在slave我的项目中不少配置是冀望在初始化模板时就主动配置好。
  • 物料方面咱们有本人一套组件库并且放在公有npm,自定义物料的形式也冀望能保留咱们以后发包构造

    • 物料:分为组件(component)、区块(block)和我的项目(scaffold)三种类型

基于上述思考,咱们做了二次开发并产出了FAW,上面将从应用成果去揭秘他的外围逻辑实现。

FAW应用成果

上面示例为新建一个微前端子利用的场景

  • 1 通过点击侧边栏激活创立我的项目流程
  • 2 抉择具体模板后点击下一步
  • 3 输出项目名称、模板版本
  • 4 如果模板提供ask-for-vscode.js文件,则依据配置生成表单

    • 次要是配置publicPathbasePathmountElementIdid...
  • 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 如果提供则依据配置项渲染为表单供开发者填写

    • 配置项个别为publicPathbasePathmountElementIdid...
  • 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`)

所以此处采纳readFileSyncnew 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