You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
import*aspathfrom'path';import*asfsefrom'fs-extra';import{run}from'./fn/shell';(asyncfunction(){constextensionsPath=path.join(__dirname,'../extensions');constextensionFiles=awaitfse.readdir(extensionsPath);// 获取 extensions 下的插件列表,挨个遍历执行 removereturnawaitPromise.all(extensionFiles.map(async(extensionFile)=>{constcwd=path.join(extensionsPath,extensionFile);if(fse.existsSync(cwd)){// link packages to extensionif(!process.env.CI){awaitremovePmworks(cwd);}constwebviewPath=path.join(cwd,'web');if(fse.existsSync(webviewPath)){// link packages to extension webviewif(!process.env.CI){awaitremovePmworks(webviewPath);}}}}),);})().catch((e)=>{console.trace(e);process.exit(128);});// 删除 @pmworks 下的依赖asyncfunctionremovePmworks(cwd: string){constcwdStat=awaitfse.stat(cwd);if(cwdStat.isDirectory()){awaitrun(`rm -rf ${path.join(cwd,'node_modules','@pmworks')}`);}}
前言
GithubBlog:#99
背景如是:
随着脚手架的提供,以及新增页面和模块的功能封装。
毕竟 多提供一层规范,就多了一层约束。 而架构的本质是为了让开发者能够将精力更加的focus 到业务的开发中,无需关心其他。比如上述脚手架初始化出来的一些模块配置、异步加载甚至一些已定义并且保留在初始化架构中的一些业务
hooks
等。如上原因,我希望能够提供一套可视化的操作(创建项目、选择依赖、添加页面,选择所需物料、配置物料属性等),一言以蔽之就是让用户对于源码开发而言,只需要编写对应的业务模块组件,而不需管理架构是如何组织模块和状态分发的,除了业务模块编码,其他都是可视化操作。
因为团队里 100%的同学都是以
vscode
作为饭碗,所以自然而然的vscode extinction
就是我的第一选择了。计划中会提供创建项目、新增页面、模块配置、页面配置、新增模块等一系列插件。后续阶段性进展,再发文总结。咳咳,是的,这将是一个源码工作台的赶脚~截止目前,已经将项目的脚手架基本搭建了个 90% ,此处作为第一阶段性总结。
成果展示
extensions
文件夹为vscode
插件的文件夹、packages
文件夹是存放公共的组件、scripts
为发布、构建、开发的脚本,其他就是一些工程配置。packages.json scripts
scripts
没有添加完全,目前开发直接npm start
发布packages
分别为npm run publish-beta:package
、npm run publish:package
,上面也有publish
的命令汇总。架构选型
目前是为了将
pmCli
功能全部封装成插件,然后通过可视化替代掉编码过程中关于架构配置的相关操作。所以插件必然不会只有一个,而是一个基于源码架构的一个操作集:多extensions
。插件中有非常多的相似功能封装。比如从gitlab
上读取基础文件、vscode
和WebView
的通信、AST
的基本封装等,所以必然需要依赖非常多的packages
,为了开发提效和集合的统一管理,必然想到基于lerna
的monorepo
的项目结构。其中关于 lerna 的一些采坑就不多说了,主要是我也只是看了市面上大部分的实践文章和官方文档,缺乏一些自己实践(毕竟感觉研究多也解决不了多大的痛点,就不想花精力了)最终的
monorepo
是基于yarn workspace
实现的,通过lerna link
来软链package
、lerna
的发布package
比较鸡肋,就参考App works
自己写了一些打包发布到预发、线上的脚本。项目工作流以及编码约束通过
husky
、lint-staged
、git-cz
、eslint
、prettier
等常规配置。编码采用
ts
编码,所以对于extensions
以及packages
中都有很多公共的配置,这里可以提取出来公共部分放置到项目根目录下(如上项目目录截图)。实践
通过
lerna init
、lerna create xxx
来初始化这里就不说了。反正完事以后就是带有一个packages
和package.json
文件的一个目录结构。项目架构
package结构
脚本封装
在项目的根目录下放置了一个
scripts
文件夹,存放着一些发布、开发以及依赖的安装的脚本啥的。getPakcageInfo.ts
代码的解释都在注释里了,核心做的事情就是,从
packages
中读取每一个package
的package.json
中的信息,然后组成需要的格式返回出去,用于发布。publish-beta-package
基本功能都在注释里了(这句话后面不赘述了),总结次脚本作用:
watch
主要借助 nsfw 的能力对本地文件进行监听。有变动,咱编译就完事了!
extensions-deps-install
因为我们的
workspace
是packages
目录下,所以针对于extensions
下的插件以及web
页面,我们没有办法通过yarn
直接install
所有依赖,随意提供了一个插件安装依赖的脚本。其实就是跑到项目目录下,去执行npm i
extension-link-package
删除本地相关的 package,让其递归向上(应用级)查找到对应软链后的 package
小小总结
核心脚本目前就如上吧,其实都是比较简单直接的功能。关于 extensions 的发布啥的还没有写,其实也可以从 appworks 中借(抄)鉴(袭)到的。等后续发布插件了再补充吧。
一个项目完成基建以后,基本就可以开工了。这里我拿创建项目来举例子吧(着重说基建部分,对插件功能和实现不展开具体的解释,第二阶段再总结吧)。
vscode extensions(vscode-webview 封装举例)
我们通过
yo code
在extensions
文件夹中去初始化一下我们要写的插件。具体的基础知识,参考官方文档:https://code.visualstudio.com/api如上以后,我们有了一个项目的基本架构,包的一系列管理,就已经可以进入到我们的开发阶段了。
毕竟我们插件是为了可视化的一系列操作,那么
vscode
的按钮和命令必然满足不了我们,需要一个操作界面:webView
。 如上图是一个带有webView
插件的整体交互过程:Common-xxx(utils)
是负责整个项目级别一些通用功能封装Extension-utils
是针对某一个插件提取的一些方法库,比如project-utils
是createProject
初始化项目时候用到的方法库,类似于一个controller
extension-service
是承载vscode
和webView
通信的一些方法提取,顾名思义:service
上面说的有些绕,与传统
MVC
不同的是这里的 view 有两个:vscode-extension
和extension-webview
举个栗子! 这里以初始化一个项目教授架为例子吧~
WebView
WebView 其实没有太多要准备的,就是准备 HTML、JavaScript 和 css 前端三大件就行了。
这里我使用的 ice 的脚手架初始化出来的项目:
npm init ice
然后修改
build.json
中的outputDir
配置,以及指定为mpa
模式码完代码以后得到我们的三大件即可。
Extensions
这里也都是常规操作,注册命令和相关回调,初始化
WebView
。这里说下getHtmlFroWebview
方法位于
packages/vscode-webview/vscode.ts
,其实就是获取一段 html,将本地资源添加vscode
协议。支持vendor
、extraHtml
等截止目前,我们已经可以在 vscode 中唤起我们的 WebView 了。
通信
然后就是解决 vscode 和 WebView 通信的问题了。这里的通信跟 pubSub 非常的类似:
插件给 WebView 发消息
webview 端接受消息
webview 给插件发消息
插件端接受
这种通信机制太零散了,在实际项目中,
webView
更加的类似于我们的view
层。所以理论上它只要通过service
去调用controller
接口去完成底层操作告诉我结果就可以:比如在创建项目的时候需要让用户选择创建目录,在 HTML 页面点击选择按钮的 click handle 应该如下:
callService
的形参第一个作为service
类、第二个作为类里面所需要调用的方法名,后续的为其对应方法的参数。正对如上,我们封装一个
callService
方法:webview
层完成了对发送时间请求、接受时间请求以及接受后取消完成(removeListener
)此次时间请求的封装。那么我们在来给extension
添加上对应的webView
需要的service.methodName
才行。这里我们再封装了一个叫做 connectService 的方法。
上面的
projectCreatorPanel
就是create 出来的WebviewPanel
的“实例”,而 services 可以理解为含有多个类的对象具体的 connectService 方法如下:
上面的代码也比较简单,就是注册监听函数,然后只要监听到
WebView
post
过来的message
,就去取对应services
下的某个service
的method
去执行,并且传入WebView
传过来的参数。extension 的 services 是在这里引入的
而
@pmworks/project-service
这个 package 里面也只是封装一些基本的方法调用。核心的处理逻辑比如下载对应gitRpo
、解析本地文件等都是在对应的extension-utils
里面进行。service只管调用即可。小小问题
如上已经完成了基本的流程封装,剩下就是具体逻辑的编写了。但是在实际开发中,web 页面需要拿到 vscode 传入的参数才行,而在 web 页面开发中,vscode 插件又没法读取未编译后的代码。如何解决呢?
在 webView 里面在封装一层 callService 用于本地 web 页面开发所需
后续展望
截止目前,基本介绍完了这两周除业务工作外的一些开发总结了。接下来需要恶补一下 vscode 插件的相关 api 准备开始操刀了。当然,在这之前,另一个非常非常紧急的任务就是还需要再升级下去年整理的源码架构,对齐下集团内现在 rax 体系的一些能力。
在回到这个插件体系(BeeDev源码工作台)的开发中,后续还需要:
如果精力有余,其实还需要个
node
后台,这样才能打通服务端和本地的能力(就是个桌面应用了呀~)好吧,不 YY,先酱紫吧~ 下一个里程碑了再总结下~~
至于项目源码。。。
参考文献
The text was updated successfully, but these errors were encountered: