Feflow是一个用于提升开发效率的前端工作流和规范工具,最新版本是v0.16.0,目前在 alpha 阶段,托管在Github上:Tencent/feflow。目前已经在NOW直播、花样直播、花样交友、手Q附近、群视频、群送礼、回音、应用宝、企鹅号等业务广泛使用。
本文将会详细介绍Feflow的技术架构和实现原理。
面临场景
目前的前端开发不得不面临工程类型多样和多技术栈的研发场景。以NOW直播为例:我们有APP内的H5业务、商业化运营活动、RN业务、小程序、组件类和 Serverless Faas 函数这6类。
面临的场景
如果没有一个很好的CLI/GUI工具,很难保证开发方式的统一,在这个背景之下,我们于17年4月开始启动 Feflow 的开发,本次版本升级主要是实现了新的开发套件机制、并且让命令体系更佳合理。
首先我们一起看看 Feflow 的整体架构的设计是怎样的呢?
架构设计
Feflow 的设计分为三层,分别是:
- 商店:包括开发套件和插件,用于项目维度和通用命令的扩展
- 内核层:包含 CLI 和 Core 两个部分,包含命令交互、命令注册、插件和开发套件的加载机制和日志模块等。
- 控制台:开发者和Feflow的命令交互层,开发者在控制台里面输入一系列的命令。
架构设计
接下来我们看看 Feflow 的命令包含哪些内容,如何通过合理的命令设计满足多栈的研发场景需要。
命令设计
Feflow 将命令划分为3类,分别是:
- 普通命令:Feflow 原生实现的命令,也就是内置命令
- 开发套件命令:项目维度的命令,不同的项目类型下命令或多或少存在差异,由开发套件提供。
- 插件命令:通过插件进行扩展的命令,插件命令更具普适性,由插件提供。
命令设计
下面一起看看开发套件和插件的定位、以及实现原理。
开发套件
开发套件用于提供某种类型的项目的命令,通常是提供多个命令的集合。Feflow的开发套件需要以 feflow-devkit-* 开头,开发套件开发完成需要发布到npm或者tnpm。
你可以把开发套件概念可以理解为类似 babel-presets 和 babel-plugin 的关系,babel-presets 是一系列 babel-plugin 的集合,开发套件其实也是由多个插件聚合而成。
上下文
Feflow 的开发套件和插件都会拥有 Feflow 的上下文环境,那么我们先看看上下文提供哪些信息,上下文会提供:
套件加载机制
如果你在某个业务项目下运行 Feflow 的命令,这个时候 Feflow 的命令加载机制是:初始化 Feflow -> 加载原生命令 -> 加载插件命令 -> 加载套件命令。其中,套件的加载机制分为项目配置文件加载和套件命令注册两个步骤。
首先 Feflow 会读取项目配置文件,项目文件名称可以是:.feflowrc.js, .feflowrc.yaml, .feflowrc.yml, .feflowrc.json, .feflowrc, package.json 中的一个。在这个配置文件里面会描述这个项目拥有的套件命令和套件命令对应的 npm 包的实现映射关系,比如:
代码语言:javascript复制module.exports = {
devkit: {
// 套件提供的一系列项目维度的命令
commands: {
// 推荐,代表着 fef dev 的命令
dev: {
// 配置格式为 `<套件>:<命令>`
builder: "@tencent/feflow-devkit-miniprogram:dev",
// 参数传递
options: {}
},
// 推荐,代表着 fef build 的命令
build: {
"builder": "@tencent/feflow-devkit-miniprogram:build",
"options": {}
},
// 推荐,代表着 fef lint 的命令
lint: {
"builder": "@tencent/feflow-devkit-miniprogram:lint",
"options": {}
}
......
}
}
}
这里面的 builder 格式是 <套件>:<命令>,比如 builder: "@tencent/feflow-devkit-miniprogram:dev"就代表要使用 @tencent/feflow-devkit-miniprogram 这个 npm 包下的 dev命令。接下来会找到套件命令的映射配置文件,在@tencent/feflow-devkit-miniprogram 包的根目录下,名称是 devkit.json,下面是 devkit.json 的内容,主要描述每个命令的对应实现,通过 implementation 字段指定。
代码语言:javascript复制{
"builders": {
"dev": {
"implementation": "./lib/command/dev.js",
"description": "Mini program development mode."
},
"build": {
"implementation": "./lib/command/build.js",
"description": "Build a mini program bundle."
}
}
}
接下来就是套件的命令注册了,这个注册逻辑和插件相同,每个套件命令通常对应一个单独的 js 文件,这个 js 文件需要 export 一个函数出来,比如:
代码语言:javascript复制// dev 命令的逻辑: lib/command/dev.js
module.exports = (ctx) => {
// 处理逻辑
};
// build 命令的逻辑: lib/command/build.js
module.exports = (ctx) => {
// 处理逻辑
};
插件
插件是为了扩展更佳通用的子命令而设计的,Feflow插件需要以 feflow-plugin-* 开头,插件开发完成需要发布到npm或者tnpm。
插件安装
插件开发好并且发布到 npm 或者 tnpm 后,接下来就是插件安装使用了。通过以下命令安装一个插件:
代码语言:javascript复制$ fef install <package>
```
Feflow 会将插件安装在 ~/.fef/node_modules
下。
插件加载
Feflow 启动时会加载 ~/.fef/node_modules 里面所有的 feflow-plugin-xx 包提供的命令,插件机制的实现类似 Redux 和 Koa2 里面的 compose 机制。
命令注册
插件的命令注册通过 Feflow 上下文提供的 commander 上的 register 方法进行注册。这个方法有3个参数,分别是:插件命令、插件命令描述、插件执行逻辑。
插件示例
最后
具体这个版本的详细 Feflow 的使用和接入指南将会在下一篇文章进行介绍。
如果你和你的团队想使用 Feflow,欢迎扫码加入讨论群: