9、架构:CLI 设计

通常大部分的程序员会更加习惯使用 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 设计

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里开业项目chat2DB-人工智能SQL分析介绍

1. chat2DB简介 1-1. 简介 ​ chat2DB是一款有开源免费的多数据库客户端工具,支持windows、mac本地安装,也支持服务器端部署,web网页访问。和传统的数据库客户端软件Navicat、DBeaver 相比Chat2DB集成了AIGC的能力,能够将自然语…

从C语言到C++_23(多态)抽象类+虚函数表VTBL+多态的面试题

目录 1. 多态(polymorphism) 1.1 构成多态的两个条件 1.2 虚函数重写(覆盖) 1.3 协变构成多态 1.4 父虚子非虚构成多态 1.5 析构函数的重写 1.6 final 和 override 关键字(C11) 1.7 重载、覆盖、隐藏的对比 2. 抽象类&am…

11、架构:CI/CD 设计

本章内容是基于 DevOps 体系的精简版本,如果有阅读过之前 DevOps 小册的同学,可以快速掠过。 开局先放一张镇楼图,上图我在行云集团做的通用型 CI/CD 解决方案 ALL IN DOCKER,所有的操作构建与发布过程都在 Docker 中操作。 但很…

J2EE自定义mvc【框架配置及功能】

目录 一、配置步骤 二、配置框架前三步 导入相应的jar 导入相应的Class 导入xml文件 三、优化基本操作(增删改) 1、基础优化 编写实体类 编写BookDao类 优化BookDao JUnit测试 2、后台优化 3、前端优化 一、配置步骤 将框架打成jar包&…

IDEA使用教程 安装教程

16. Codota 插件 Codota 插件可以根据使用频率优先显示较常用的类和方法。然而,是否使用该插件取决于个人的偏好。有时工具只能作为参考,仍然需要依靠个人记忆来确保准确性。 17. 快速查看类和字段的注释 按下 F2 键可以快速查看某个类或字段的文档注…

从JDK源码级别剖析JVM类加载机制

1 什么是Java虚拟机 一个可执行java字节码的虚拟机进程;跨平台的是java程序,而不是java虚拟机,java虚拟机在各个操作系统是不兼容的,例如windows、linux、mac都需要安装各自版本的虚拟机,java虚拟机通过jdk实现功能。…

【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 文章目录 系列文章目录前言一、所有权(Ownership)1.1.、所有权(Ow…

【MySQL】不就是子查询

前言 今天我们来学习多表查询的下一个模块——子查询,子查询包括了标量子查询、列子查询、行子查询、表子查询,话不多说我们开始学习。 目录 前言 目录 一、子查询 1. 子查询的概念 2. 子查询语法格式 2.1 根据子查询结果不同可以分为:…

flutter聊天界面-Text富文本表情emoji、url、号码展示

flutter聊天界面-Text富文本表情emoji、url、号码展示 Text富文本表情emoji展示,主要通过实现Text.rich展示文本、emoji、自定义表情、URL等 一、Text及TextSpan Text用于显示简单样式文本 TextSpan它代表文本的一个“片段”,不同“片段”可按照不同的…

Matlab画等构造图

clc;clear;close all; data xlsread(TOPBRENT等T0构造.xlsx); x data(:,1) xmax max(x); xmin min(x); y data(:,2) ymax max(y); ymin min(y); z data(:,3); N 45; …

IDEA使用插件绘制UML类图+PlantUML语法讲解

安装 IDEA安装插件 安装完插件记得重启一下IDEA 安装Graphviz(亲测win11可以使用) 安装完插件之后,还需要安装Graphviz才可以渲染图形。 Graphviz安装包下载地址 安装过程很简单,直接双击或者管理员身份运行即可,注…

Docker中部署Redis集群与部署微服务项目的详细过程

目录 一、使用Docker部署的好处二、Docker 与 Kubernetes 对比三、Redis集群部署实战四、Spring Boot项目 打包镜像?小结 一、使用Docker部署的好处 Docker的好处在于:在不同实例上运行相同的容器 Docker的五大优点: 持续部署与测试、多云服务平台支…

微信小程序开发与应用——字体样式设置

要求:设置字体样式。 1、打开微信开发者工具,创建一个小程序,如下: 2、设置小程序的项目名称和路径,并选择开发语言为JavaScript,如下: 3、小程序的主体部分由三个文件组成,且都要…

VS2019+Qt5.15 在线显示百度地图

1.Qt5.15编译程序需要选择mscv2019 Release版本 2.需要到百度地图开发平台注册并获取到开发者key 3.显示地图是JS与Qt的交互过程&#xff0c;显示地图的html文件&#xff1a; <!DOCTYPE html> <html><head> <meta name"viewport" content&q…

基于ubuntu的驱动开发

一般的linux驱动开发都是基于交叉编译来进行的&#xff0c;本文尝试着从另一个角度&#xff1a;基于ubuntu的本地驱动开发来学习一下驱动的开发 一、驱动的开发与编译 1.1、编写驱动文件 #include <linux/init.h> #include <linux/module.h> static int hello_i…

深入理解Linux网络——内核是如何接收到网络包的

文章目录 一、相关实际问题二、数据是如何从网卡到协议栈的1、Linux网络收包总览2、Linux启动1&#xff09;创建ksotfirqd内核线程2&#xff09;网络子系统初始化3&#xff09;协议栈注册4&#xff09;网卡驱动初始化5&#xff09;网卡启动 3、迎接数据的到来1&#xff09;硬中…

Gradio库中的Model3D模块:实时上传和展示3D模型

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

结合具体场景举例说明chatgpt预训练模型中Tokenization的原理

假设我们有一个场景&#xff0c;Alice想向Chatbot询问一部电影的推荐。她发送了一条消息&#xff1a;“你好&#xff0c;能给我推荐一部好看的电影吗&#xff1f;” 在这个场景中&#xff0c;Chatbot使用了ChatGPT预训练模型。首先&#xff0c;Chatbot需要对Alice的消息进行Tok…

OpenCV读取一张8位无符号三通道图像并显示

#include <iostream> #include <opencv2/imgcodecs.hpp> #include <opencv2/opencv.hpp> #include

c++编写网络爬虫

c爬虫项目 实现图形化界面UI 安装easyX&#xff08;需要用的graphisc.h&#xff09; 我之前的文章详细写到过如何安装。是这篇文章提到的&#xff1a;传送门 easyx官网 创建图形化界面 #define WINDOW_WIDTH 482 #define WINDOW_HEIGHT 300 void initUI() {initgraph(WINDO…