本篇文章重要引见腾讯IVWEB团队从0到1在工程化的思索和实践。feflow的全称是Front-end flow(前端工作流),致力于提拔研发效力和范例的工程化处置惩罚方案。愿景是经由历程feflow,能够使项目建立、开辟、构建、范例搜检到终究项目上线的全部历程越发自动化和标准化。
要处置惩罚的题目
- 项目的目次构造按商定天生
- 团队有一套开辟范例举行束缚
- 支撑多种范例的构建,包括Fis构建和webpack构建
- 团队内部的代码孝敬统计、离线包内置App等
为了处置惩罚上述题目,我们于17年2月尾最先投入工程化feflow东西的开辟和相干范例的制订,现在已研发出了 feflow 的 CLI 版本,后续会推出 GUI 版本。
架构设想
为了让 feflow 的具有高可扩大性,我们设想了4层构造,分别是:插件生态、内核层、参数剖析器和掌握台。除了贯串全部开辟工作流的基本敕令挑选经由历程内部插件内置在CLI 的Core内里,别的非必要敕令一致经由历程插件机制举行扩大。
另一方面,为了使得 feflow 能够实用多种范例的项目。我们开辟了多种范例的营业脚手架,如:运动模板、App H5模板、RN模板和营业组件模板。
实行历程
当用户在掌握台内里输入某个敕令。起首会经由历程CLI 的参数剖析器,将这个敕令剖析成一个object对象,然后传递给CLI 的内核。一切的敕令都是经由历程内核上下文供应的 register 函数 举行注册的,一方面内核本身会读取内置插件 注册的基本敕令,另一方面,内核会读取当地已装置的外部插件注册的敕令。假如找到用户输入的敕令则最先实行敕令对应的回调函数。
基本敕令设想
# 初始化项目
$ feflow init
# 当地开辟
$ feflow dev
# 代码质量搜检
$ feflow lint
# 打包构建
$ feflow build
# 代码宣布
$ feflow publish
# 装置插件、脚手架等
$ feflow install package
# 设置当地客户端,如: npm 的源和 proxy
$ feflow config <key> <value>
前面提到,CLI 的敕令包括两部份,分别是内置在内核里的基本敕令和外部插件供应的敕令。那末外部插件要怎样设想呢?
插件机制设想
插件完成道理
这里有一个异常奇妙的设想,经由历程运用node供应的module和vm模块,能够通注入feflow全局变量来接见到cli的实例。从而能够接见cli上的种种属性,比方config, log和一些helper等。
loadPlugin(path, callback) {
const self = this;
return fs.readFile(path).then((script) => {
const module = new Module(path);
module.filename = path;
module.paths = Module._nodeModulePaths(path);
function require(path) {
return module.require(path);
}
require.resolve = function(request) {
return Module._resolveFilename(request, module);
};
require.main = process.mainModule;
require.extensions = Module._extensions;
require.cache = Module._cache;
// Inject feflow variable
script = '(function(exports, require, module, __filename, __dirname, feflow){' +
script + '});';
const fn = vm.runInThisContext(script, path);
return fn(module.exports, require, module, path, pathFn.dirname(path), self);
}).asCallback(callback);
}
敕令注册:
敕令须要以feflow.cmd.register举行注册,比方:
feflow.cmd.register('deps', 'Config ivweb dependencies', function(args) {
console.log(args);
// Plugin logic here.
});
申明:
- register有3个参数,第一个是子敕令称号,第二个是敕令形貌申明信息,第三个是对应的子敕令实行逻辑函数。
- feflow会将敕令行参数args剖析成Object对象,传递给插件处置惩罚函数
设置
能够经由历程feflow.version猎取当前feflow的版本,feflow.baseDir 猎取feflow跟目次(在用户目次下的.feflow),经由历程feflow.pluginDir 猎取插件目次
日记
经由历程feflow.log来举行相干敕令行日记输出
const log = feflow.log;
log.info() // 提醒日记,掌握台中显现绿色
log.debug() // 调试日记, 敕令行增添--debug能够开启,掌握台中显现灰色
log.warn() // 正告日记,掌握台中显现黄色背景
log.error() // 毛病日记,掌握台中显现赤色
log.fatal() // 致命毛病日记,,掌握台中显现赤色
装置
插件开辟完成后,能够经由历程 feflow 供应的 install 敕令装置插件。装置的插件会安排在当地客户端 ~/.feflow/node_modules 文件夹下,而且写入到 ~/.feflow/package.json 中
$ feflow install feflow-plugin-xxx // 装置某个插件
以后每次运转敕令时,便会从当地加载插件所注册的敕令
全量更新和增量更新
当CLI宣布了一个新的版本,能够我们会烧毁掉某些功用或许供应了新功用。这个时刻假如用户依旧运用的是旧版本,因为某些效劳已烧毁掉了则会报错。在这类新旧版本不兼容的情况下,怎样强迫用户举行CLI的晋级呢?须要在运转敕令之前搜检当地的CLI是不是和长途供应的新版本是不是兼容。在新旧版本不兼容时,会强迫全量更新。怎样推断当前用户装置的当地版本和长途最新版本是不是兼容呢?
这里异常奇妙的运用了一下 npm 的 registry机制,每次宣布新版本,我们会在 package.json 内里新增一个自定义字段 compatibleVersion,它的值是一个 semver 的版本号。当地搜检时,会读取当地已装置的版本和长途最新的版本举行比较,看看是不是满足 compatibleVersion 的请求。假如不满足,则会自动运转 npm install feflow-cli
到最新的版本。
"configs": {
"compatibleVersion": ">=0.13.0"
},
关于插件,采用的是增量更新机制。每一个宣布到 npm 上的插件的package.json 中一样会有上面的这个字段,关于当地装置的不兼容的插件列表,会采用增量更新。
多范例脚手架的架构设想
项目拷贝存在的题目不言而喻,大抵有以下三个方面:
- 轻易失足;一旦某个症结文件拷贝丧失或许毛病,极能够须要消耗半天到一天的时候排查环境题目。
- 差别场景下对目次构造请求差别;日常平凡开辟历程当中,工程通常会分为运营运动、Hybrid营业、进口级别的项目(对机能和体验有极致和刻薄的请求)。须要基于RN或许Node.js的首屏直出,另有经常使用的营业组件等的开辟。
- 新的Feature和BugFix难以同步;某个同砚开辟历程当中增添的新方法或许处置惩罚的bug很难传递给别的同砚而且沉淀成履历积聚下来。
社区内里供应了圆满的Yeoman处置惩罚方案,它是为了自动化项目的建立而生。Yeoman建立项目包括以下几个阶段:
- initializing: 初始化一些状况之类的,通常是和用户输入的 options 或许 arguments 打交道
- prompting: 和用户交互的时刻(敕令行问答之类的)挪用
- configuring: 保留设置文件(如 .babelrc 等)
- writing: 天生模板文件
- install: 装置依靠
- end: 完毕部份,初始代码自动提交
我们只须要继续Yeoman的Generator类做模板定制化,基于Yeoman的脚手架设想思绪应当如下图所示:
当开辟者输入 feflow init 敕令时,开辟者会通知CLI须要建立哪种范例的项目,CLI收到敕令后。从当地已装置的Yeoman脚手架内里挑选某种范例的模板。然后,CLI会挪用Gitlab API在长途建立堆栈而且授与开辟者master权限。接下来,会依据现实营业场景须要,自动化请求一些办理信息,罕见的如离线包id,监控告警id等等。以后,在当地目次天生代码而且装置项目依靠的npm包,末了将本次初始化天生的一切代码自动提交到长途Git堆栈。
多范例主流构建支撑
为了让feflow 支撑多种范例的构建环境,比方 Fis3 和 webpack,或许前不久刚推出的号称零设置本钱的 Parcel 构建。在每一个项目的跟目次会安排一份设置文件,称号为 feflow.json。它的设置多是如许的:
{
"builderType": "builder-webpack3",
"builderOptions": {
"moduleName": "mobile",
"bizName": "category",
"minifyHTML": true,
"minifyCSS": true,
"minifyJS": true,
"usePx2rem": true,
"remUnit": 100,
"remPrecision": 8,
"inject": true,
"port": 8001
}
}
builderType为构建的npm包,builderOptions为构建的参数设置。
末了
腾讯IVWEB团队的工程化处置惩罚方案feflow已开源:Github主页:https://github.com/feflow/feflow
假如对您的团队或许项目有协助,请给个Star支撑一下哈~