9、架构:CLI 设计

news2024/11/26 0:53:50

通常大部分的程序员会更加习惯使用 CLICommand-Line Interface 命令行界面)来辅助开发业务,包括初始化、更新、构建、发布等功能,可以获得沉浸式一站的开发体验。

在之前有一篇企业级 CLI 开发实战介绍过如何开发一款适用团队的 CLI 工具,基于团队规范可以将项目脚手架与 CLI 强制绑定在一起,约束开发者使用的开发语言以及开发规范,但是对于一款通用性的低代码产品,基于业务类型的物料开发经常会存在个性化的需求,强行将构建与 CLI 绑定则会使得 CLI 本身的逻辑变得更加复杂。

所以本次 CLI 的设计会更加较为通用,不再与单纯的业务开发耦合过多。

初始化工程/管理


由于物料会根据业务的不同存在不同的配置属性,每一次开发物料都需要拉取对应的业务模板,所以我们会面对种类非常以及多个版本的情况,以下是拉取模板的流程图:

nodegitdownload-git-repo 和 git-clone 都是用于在 Node.js 环境中从远程 Git 仓库中下载代码的库,它们之间的主要区别如下:

  • 功能:nodegit 是一个完整的 Git 库,提供了一套完整的 Git API,可以用于管理 Git 仓库、提交代码等操作。download-git-repo 和 git-clone 则是专门用于下载 Git 仓库中的代码的库。
  • 依赖:nodegit 和 git-clone 都依赖于 libgit2 库,而 download-git-repo 则不依赖于任何第三方库。
  • 使用方式:nodegit 和 git-clone 都是使用 Git 命令行工具来下载代码,而 download-git-repo 则是直接调用 Git 仓库的 API 来下载代码。

除了拉取模板之外,我们还会借助封装的 CLI 来管理工程,所以最终会选择 nodegit 进行二次封装,简化使用过程中 Git 操作的命令。

权限


使用 Open Api 与用户系统进行交互,通常情况下只有登录与鉴权两个模块。

登录

  • 一般都是登录之后将 token 缓存在本地,过期之后再重新授权。
  • 如果嫌麻烦,也可以直接加密缓存用户名与密码,再过期之后自动调用登录接口维持登录态,这样可以让用户后期无感知使用。

权限

为了保证项目使用的安全性,一般在每一次执行部署操作之前都需要进行权限判断,权限判断的方式也有如下两种:

  • 每一次都直接调用接用户中心的权限接口判断,当然如果碰到网络延时的话,每一步的操作都很艰难。
  • 为了减少网络延时可以在每个工程创建之后就预先缓存对应过程的权限信息,当权限不足进行权限申请,当审批通过后可以手动刷新权限数据或者设定缓存过期时间来定时拉取权限数据。

构建


由于新的 CLI 设计将不再与脚手架耦合,所以构建的具体配置将内置在脚手架中,例如:RollupWebpackVite 等。

CLI 将只接受构建前、构建、构建后三种构建命令并执行,通常情况下可以与脚手架约定俗成比如:

  • npm run pre 构建前执行脚本
  • npm run build 构建脚本
  • npm run did 构建完成之后执行脚本

或者使用配置文件自定义其他的运行命令:

{
    "pre-build":"npm run pre",
    "build":"npm run build",
    "build-did":"npm run did"
}

除此之外,构建过程还需要区分各个环境并注入对应的环境变量,让实际工程构建的过程中根据环境变量选择不同的配置。

部署


一般前端服务的部署有如下几种:

  1. 静态文件部署:将前端应用程序打包成静态文件,并将这些文件上传到 Web 服务器或 CDN 上。用户在访问网站时,直接从 Web 服务器或 CDN 上获取静态文件,然后在浏览器中渲染。
  2. 容器化部署:使用容器技术,如 Docker,将前端应用程序打包成容器镜像,并在生产环境中部署这些镜像。这种方式可以提高部署的可重复性和可移植性,并且可以更方便地进行版本管理。
  3. 云平台部署:将前端应用程序部署到云平台上,如阿里云、AWS等。这种方式可以提供更好的可扩展性和可靠性,并且可以根据需要自动扩展服务器资源。
  4. 私有部署:将前端应用程序的代码发布到生产环境[私有服务器]中,然后在生产环境中使用类似 Nginx 或 Apache 的 Web 服务器来运行和管理应用程序。

一般来说,纯前端的项目直接使用静态文件部署即可,所以我们的 CLI 需要内置一些 OSS 的工具函数,方便将资源上传到对应的 OSS 服务。

非纯前端的项目建议走 Docker 发布,配合 k8s 的可以更方便的伸缩扩容,同时配合启动环境变量注入,使得多环境中代码可以保持一致,减少错误。

无论是哪种模式都需要针对不同的平台进行适配,比如不同服务商的 OSS 工具以及不同 k8s 平台等,虽然一般的小团队不会有很多的选择性,直接内置在 CLI 中也问题不大,但作为通用性的工具,我们在开发过程这一会设计成拓展插件,减少用户的接入成本。

自定义插件


除了上述一些基础服务之外,CLI 还应该具备拓展插件的能力,使之功能更加完善,例如上一步骤中部署到各个环境的工具类就可以以对应的拓展插件提供。

CLI 需要先对命令进行分析判断是基础命令还是拓展服务,所以需要一个类似 Router 的主入口,包含内置与第三方插件的命令,在用户输入命令之后,调用不同的插件,流程图如下所示:

对于主 CLI 来说,很难接受规范不一致的三方插件注册,这样会影响 CLI 的结构,所以我们需要对 CLI 插件的模板做一个约束,除了输出的格式与上述内置插件格式保持一致之外,我们还需要对插件名称、依赖等等做一个约束,并且提供各种 Hook 方便插件开发,可以参考 Webpack 的 tapable 实现。

对于 @Ignition/cli 来说,将只接受 @Ignition/cli-plugin-*** 命名格式的插件进来。这种规则可以根据团队的命名规范来约定,并不是唯一规范。

所以在添加插件的时候需要做两次校验,第一层校验是通过校验名字,第二层是安装依赖,如果依赖安装失败也不会添加成功。

在之前工程化里面有对自定义插件有一些实战的介绍,有想先试试的同学可以先参考前端工程化实战 - 自定义 CLI 插件开发玩起来,后期出实战篇的时候,会比之前的更加详细。

注意


以上 CLI 所有的操作都是基于开发者的本地环境进行操作,与云上 CI/CD 不同,在开发者本地进行构建部署是依赖本地的环境,大部分的时候都存在分支管理、依赖不同步的问题。

为了避免构建代码遗失以及环境不一致的问题,我们需要根据下述流程来约束:

当然 CLI 可以不做本地构建,而是触发远程构建命令直接走云上构建,将结果实时反馈到本地,虽然会更加可靠,但是开发工作量也就相对增加了,如果有能力我建议选择云上构建。

额外拓展


避免有些同学对文章开头所说的 CLI 与脚手架剥离有误会,这里对这两者进行一些简单的介绍。

首先 CLI 和脚手架都是可以用于快速生成项目代码的工具,但它们的作用和功能略有不同:

  • CLI 是一个命令行界面工具,可以用来执行一系列命令,完成各种操作,如代码构建、打包、测试等,也可以用来管理项目依赖、配置文件等。同时 CLI 可以非常灵活地适应不同的项目需求,可以通过编写插件和扩展来实现更多的功能。
  • 脚手架(Scaffolding)是一个用于生成项目代码的工具,通常包含了项目的基本结构、依赖、配置等信息,可以帮助开发者快速创建一个新项目,并提供一些基础设施和工具,如构建工具、测试框架、代码风格检查等。减少开发者的重复工作,提高开发效率,同时也可以保证项目的一致性和可维护性。

综上所述,虽然 CLI 和脚手架都具备快速初始化项目的能力,但 CLI 更加灵活,可以根据具体需求来执行各种任务,而脚手架则更加专注于项目结构和基础设施的搭建。

将脚手架的能力从 CLI 分离之后,为了拓展性更好、更规范的话,通常会创建一个基础的脚手架,以此脚手架再拓展各个业务模板,但想节约工作量或者各个业务需求的差异化更大的话,可以直接根据不同的模板定制脚手架就好。

写在最后

如果你有什么疑问或者更好的建议,欢迎在评论区提出。 👏

9 架构:CLI 设计

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/722701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

了解k8s容器组pods

一:Pods概述 在 部署第一个应用程序 中创建 Deployment 后,k8s创建了一个 Pod(容器组) 来放置应用程序实例(container 容器) Pod 容器组 是一个k8s中一个抽象的概念,用于存放一组 container&a…

yolov5增加AFPN-全新特征融合模块AFPN,效果完胜PAFPN

论文学习:AFPN: Asymptotic Feature Pyramid Network for Object Detection-全新特征融合模块AFPN,完胜PAFPN_athrunsunny的博客-CSDN博客 先上配置文件yolov5s-AFPN.yaml # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license# Parameters nc: 80…

Nginx安装与介绍

Nginx概述 Nginx (“engine x”) 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强,事实上 Nginx 的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用 Nginx 网站用户有:百度、京东、新浪…

Windows11最新版官网制作系统盘

在百度里搜索"windows11官网下载",然后选择微软官网的链接: 下載 Windows 11https://www.microsoft.com/zh-tw/software-download/windows11 然后就可以制作U盘windows11官网系统的安装U盘了。

进行APP广告变现之前,媒体需要关注哪些APP运营的信息指标

在进行广告变现之前,媒体商务或运营人员首先要知道自家 APP 的一些基本体量信息及基本用户使用情况信息。唯有充分而全面的掌握并罗列出这些基础 APP 运营指标,才能便于媒体通过自家真实流量规模、实力等来预估广告位价值,或更好的像广告需求…

设计模式--------创建型模式

创建型模式 用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”。GoF(四人组)书中提供了单例、原型、工厂方法、抽象工厂、建造者等 5 种创建型模式。 1.单例设计模式 单例模式(Singleton Pattern&#xff09…

如何截取视频中的一段视频?简单的截取方法分享

如果我们只需要处理视频中的某一部分,就可以将这一部分的内容截取下来,可以省去处理整个视频文件的时间和精力。此外,截取视频也可以让更加方便地分享和保存视频内容。此外,如果我们只需要分享视频中的一部分给他人观看&#xff0…

二、MongoDB 安装集

一、MongoDB—Docker mongoNoSQL Manager for MongoDB: L1、L2 1. 创建容器 docker search mongo docker pull mongodocker run -d --namemongo_1 -p 27017:27017 \-v /root/mongo/configdb:/data/configdb/ \-v /root/mongo/db/:/data/db/ \[镜像ID] --auth2. 登…

【软件测试】盘一盘工作中遇到的 Redis 异常测试

目录 前言: 一、更新 Key 异常 二、Key的删除和丢失 三、KEY 过期策略不当造成内存泄漏 四、查询Redis异常时处理 五、redis 穿透、击穿、雪崩 六、Redis死锁 七、Redis持久化 八、缓存与数据库双写时的数据一致性 前言: 在软件测试过程中&…

第八章、【Linux】文件与文件系统的压缩,打包与备份

8.1 压缩文件的用途与技术 8.2 Linux 系统常见的压缩指令 列几个常见的压缩文件扩展名: 8.2.1 gzip, zcat/zmore/zless/zgrep gzip 可以说是应用度最广的压缩指令了!目前 gzip 可以解开 compress, zip 与 gzip 等软件所压缩的文件。 当你使用 gzip 进…

Error: 系统错误,错误码:80051,source size 2649KB exceed max limit 2MB [202306

小程序主包体积过大,预览到手机失败 把这个勾选一下,上限调整到4MB

Android性能优化问题方案的总结~

虽然总说“英雄不问出处”,但大厂卡学历是默认的“潜规则”。不过最近一个老弟,让我挺振奋的!人家完全靠实力上岸。他就属于死磕型的,是我近2年见过的少有的Android性能优化高手。 要说他也挺聪明,贼会选领域。你出去随…

力扣 -- 740. 删除并获得点数

题目链接&#xff1a;740. 删除并获得点数 - 力扣&#xff08;LeetCode&#xff09; 下面是用动态规划的思想解决这道题的过程&#xff0c;相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 参考代码&#xff1a; class Solution { public:int deleteAndEarn(vector<…

【MySQL】 MySQL安装

文章目录 1. MySQL安装配置内置环境关闭MySQL卸载MySQL确认环境是否干净 配置MySQL yum源yum源 的安装注意事项检测是否安装成功 MySQL的启动MySQL的登录登录方案一 获取临时密码登录方案二 免密码登录 MySQL的配置文件 1. MySQL安装 配置内置环境 输入 ps axj | grep mysql …

SpringBoot教学补充资料3-Maven安装

Maven下载地址&#xff1a;https://maven.apache.org/download.cgi 下载后进行解压&#xff0c;记住解压路径。 mvn -v

大文件下载

背景 google chrome下载大文件的时候&#xff0c;没有断点续传的功能&#xff0c;会因为网络不稳定多次下载失败。 google drive大文件 安装google drive客户端 点开别人的goole drive链接&#xff0c;保存在自己的文件夹下 本人的goole drive获取file_id # 链接格式 h…

mapbox icon-allow-overlap 和 icon-ignore-placement的区别

icon-allow-overlap 和 icon-ignore-placement的区别 官网解释&#xff1a;If true, the icon will be visible even if it collides with other previously drawn symbols. 翻译&#xff1a;如果该属性为true那么他会显示即便会冲突和在它之前已经添加的图层。 官网解释&am…

NSS [鹏城杯 2022]简单包含

NSS [鹏城杯 2022]简单包含 看代码觉得不就直接post flagdata://text/plain,<?php system(ls);?>行了。 但是事实上没有什么软用。 用了php://伪协议之后发现有WAF。 可以读源码 解码得到 <?php$path $_POST["flag"];if (strlen(file_get_contents(ph…

UE5 MetaHuman SDK插件的使用【一、编辑器创建音波与蓝图创建获取音波,语音与嘴唇口型的同步】

目录 打开插件 创建音频 编辑器这直接创建音频&#xff1a; 蓝图中创建和获取音频&#xff1a; 唇语&#xff1a; 声音与嘴唇同步&#xff1a; 方法一【效果不是很好】&#xff1a; 方法二【效果很好&#xff0c;但有一段时间延迟在处理】&#xff1a; 逻辑&#xff1…

Mysql数据库,Navicat上给表创建索引一直等待

问题背景&#xff1a; 对查询语句进行索引优化&#xff0c;针对以下表添加联合索引&#xff0c;语句如下&#xff1a; ALTER TABLE hzz_patrol_period_config add index IDX_PERIOD_CONFIG_YEAR_TYPE_VAL (EFFECT_YEAR,CHECK_CYCLE_TYPE,CHECK_CYCLE_VAL); Navicat上执行一直…