UNPKG

futu-cli

Version:

A simple CLI for scaffolding futu5_ipo projects.

187 lines (112 loc) 6.49 kB
# Futu5 Node.js 接入层脚手架方案 ## 背景 目前开发基于 futu5 node.js 接入层为基础的项目时,直接从之前的项目copy过来然后进行修改。表面上看问题不大,但其实存在很多问题: * 重复性工作,繁琐而且浪费时间 * copy过来的模板容易存在与个人需求无关的代码 * 人工操作永远都有可能犯错,建新项目时,总要花时间去排错 * 项目中有很多需要配置的地方,容易忽略一些配置点,进而埋坑 * 缺乏版本控制:内部框架也在不停的迭代,人工建项目往往不知道框架最新的版本号是多少,使用旧版本的框架可能会重新引入一些bug * 新的 feature 和 bug fix 难以同步 针对以上问题,开发人员可以根据交互动态生成项目结构、自动添加依赖和配置、移除不需要的文件的脚手架工具是有必要的。 像我们熟悉的 `vue-cli,react-native-cli` 等脚手架,只需要输入简单的命令 `vue init webpack project`,即可快速帮我们生成一个初始项目。因此,在实际工作中,我们可以定制一个属于自己的脚手架,来提高自己的工作效率。 ## 需求分析 ![需求分析](./imgs/final/13.jpg) 命令格式: ```bash # 命令 futu5 init '<template-name>#[branch-name]' [project-name] # options # 使用 git clone 方式下载模版,默认 http -c, --clone # 输出帮助信息 -h, --help # 使用本地缓存模版模式 -o, --offline ``` 命令示例: ```bash # 根据模版创建项目 futu5 init futu5_ipo my-project # 根据指定模版版本创建项目 - 拉取指定分支 futu5 init futu5_ipo#1.0 my-project # 使用本地缓存模版创建项目 futu5 init futu5_ipo my-project -o # 使用 git clone 方式下载模版创建项目 futu2 init futu5_ipo my-project -c ``` ## 方案介绍 ![方案介绍](./imgs/final/12.png) ## 方案比较 ![方案比较](./imgs/final/10.png) ## 方案优劣 ![方案优劣](./imgs/final/11.png) 因此,本次将采用 vue-cli 脚手架方案进行开发,以下是脚手架分析: ## 系统结构 * 用户输入指定命令及参数,脚手架解析出目标项目名称、目标项目构建路径、模版仓库 * 脚手架从模板仓库拉取模板文件,然后根据模板仓库根目录下定义描述文件进行收集问题 * 脚手架结合所收集问题答案过滤文件并生成接入层项目基本框架 ![系统架构](./imgs/final/1.png) ## 主流程图 ![流程图](./imgs/final/9.jpg) ## 核心功能 ### 1. 命令及参数解析 脚手架根据用户输入的命令及参数(progress.argv 包含当启动 Node.js 进程时传入的命令行参数)进行解析获得模版仓库地址/模版名(模版仓库地址为第三方扩展模版)、模版版本、下载模版的方式(http/clone)、目标项目构建路径、目标项目名称等。 ![命令及参数解析](./imgs/final/2.png) ### 2. 目标项目构建路径判断 脚手架根据解析用户输入所得 **目标项目构建路径** 进行判断(是否已存在、是否是当前目录)。 ![目标项目构建路径判断](./imgs/final/3.png) ### 3. 模板下载 脚手架根据解析用户输入所得 **模版仓库地址/名** 拉取模版文件。 ![模板下载](./imgs/final/4.png) ### 4. 模版配置文件解析 解析所拉取模版文件下包含的模版定义数据文件(即 `[meta.{js, json}](https://github.com/vuejs-templates/webpack/blob/develop/meta.js)`)。该文件描述初始化项目时命令行的交互动作及文件过滤依据(即关于目标项目名称、目标项目描述、目标项目依赖配置选择等问题的定义)。返回模版配置对象。 ![模版定义数据解析](./imgs/final/5.png) ### 5. 问题收集`meta.js` 或者 `meta.json` 模版配置对象中的 `prompts`字段解析成对应的问题询问,并收集答案存于 `metalsmith.metadata()`。 ![问题收集](./imgs/final/6.png) ### 6. 文件过滤 根据问题答案收集所得 `metalsmith.metadata()` 删除一些不需要的模版文件。 ![文件过滤](./imgs/final/7.png) ### 7. 模板渲染 将已过滤模版文件中内容含模版引擎语法的文件内容替换成 `render` 函数(对模版文件的变量占位符实现动态插值)的返回,其他文件保持不变。 ![模板渲染](./imgs/final/8.png) ### 8. 输出提示信息 输出项目启动帮助信息。 ## 技术选型 ### 1. 使用语言:Node.js ### 2. 命令及参数解析:commander.js * 将用户输入参数项解析成一个对象的属性 * 如,可直接通过 `program.clone` 知道模版的下载方式 * 简化了命令行开发 ### 3. 路径存在判断:fs.existsSync(path) ### 4. 模板下载:download-git-repo * 下载并提取 git 仓库,用于下载项目模板 * 支持 clone 以及 http 模式 ### 5. 问题收集:inquirer.js * 用于与用户进行交互,接受一个问题对象的数组 * 在用户与终端交互过程中,将用户的输入存放在一个答案对象 * 支持多种类型的问题形式:confirm、数组、字符串、checkbox、password、editor等 * 支持根据前面问题回答情况决定后面问题是否需要进行提问 ### 6. 文件读取:metalsmith * 一个简单的静态网站生成器,可插拔。所有的逻辑都是由插件来处理的。以文件流的形式链接起来。 * 工作原理: * 读取源目录中的所有文件。 * 调用一系列操作文件的插件。可在处理文件时使用中间件来对模版进行处理 * 将结果写入目标目录 * 在本项目中: * 读取模版目录中所有文件 * 调用自定义文件处理中间件:询问问题、过滤文件、渲染模版 * 将结果写入目标目录 ### 7. 过滤文件:minimatch * 文件匹配 ### 8. 模板引擎:handlerbars * 模板文件中通过 handlerbars 引擎去处理与项目依赖等相关的模版文件。 ### 9. 模板渲染:consolidate * 模板引擎结合体。 * 在使⽤时,输⼊统⼀的模版数据对象及配置即使后期更换模版,也不必在主逻辑中修改,只需把引⼊的 render 函数改成其他模版引擎的 render 函数 ### 10. 模版配置对象解析 * 读取 json 文件:read-metadata * 检验项目名是否合法:validate-npm-package-name ### 11. 其他 * 加载等待动画:ora * 高亮终端打印输出信息: chalk