插件开发
#
编写插件Nidle的任务是通过插件去执行的,可以通过编写插件扩展自己的自动化部署流程。
#
创建插件一个插件由以下构成
- 一个具名 JavaScript 函数。
- 在它的原型上定义 apply 方法。
- 在 apply 方法中往调度器 add、addParallel(挂载) 任务处理方法。
- 方法是个通过
p-cancelable
封装的 可取消Promise 对象(因为任务基本是异步的,特别是shell命令是在单独进程中异步处理的,需要在取消的时候主动kill掉),内部通过 task 实例可以获取到 构建相关内容,并可进行相应操作。 - 在实现功能后结束 Promise。
const PCancelable = require('p-cancelable')
class ExamplePlugin { apply (scheduler) { // 串行任务 scheduler.add('name', (task, config) => { return new PCancelable((resolve, reject, onCancel) => { // ... onCancel(() => { // 取消异步操作 }) }) })
// 并行任务[Remove] scheduler.addParallel('name', (task, config) => { return new Promise((resolve, reject) => { // ... }) }) }
input (options) { // options为input默认配置的options,可以用来控制不同的场景返回不同的inputs // inquirer question list return [ { type: 'input', name: 'test', message: 'xxx' } ] }}
#
add 挂载说明add(name, callback)
- 添加串行方法,任务默认都是串行执行的addParallel(name, callback)
- 添加并行方法,当任务是完全独立并确认不会影响到后续流程时(如 图片压缩),那么可以进行并行处理,以优化构建效率
danger
暂不支持并行方法 串行和并行方法内部实现是一致的,所以内部是可以混用;当任务阶段关闭并行执行时,系统会提示一个 warning 提示,将并行方法进行串行执行
#
input说明input输入需要同时支持 CLI
和 SPA
端,所以我们进行了以下技术选型:
CLI端
- 基于强大的 inquirer 交互式命令行SPA端
- 基于antd-pro的 schema-form 配置化表单生成方案
为了同一配置支持两端,我们做了以下取舍
inquirer
的输入类型相对于form
少,为了减少适配成本,所以优先考虑支持inquirer
- 在
SPA端
我们需要对inquirer question
进行一次转换,转换成schema
- 因为每个插件都可能有
input
,输入的时候需要进行分组,所以inquirer
需要在question name
=${plugin.name}.${question.name}
CLI端
、SPA端
需要对输入项进行分组
#
inquirer支持特殊说明Form表单并不能完全支持inquirer的所有场景,所以我们进行了以下取舍(未特殊说明则默认支持)
- 不支持editor类型,实在是想不到使用场景
- message、default、choices不支持Function类型,也就是不支持基于前面回答动态修改这些值
- 不支持filter、transformer、when,因为Form不支持
- 不支持pageSize、prefix、suffix、askAnswered、mask,因为Form不支持
- 不支持choices的checked属性设置选中项,请使用default
#
task实例{ name: '', // 应用名 mode: 'development', // 环境 repository: { // git repository }, type: 'publish', // 构建类型, default `publish` processOptions: { // process option execPath: process.execPath }, source: '', // 源代码目录 output: { path: '' // 编译输出 }, logger: logger // 日志}
#
process 说明如果多应用之间基于不同 node 版本开发,并且通过 nvm
进行版本管理,那请关注这里
如果插件是通过子进程执行 shell 命令,像 npm install
、编译
相关都是依赖应用需要的 node version
,在使用 nidle-nvm
插件的情况下,task 实例中的 processOptions.execPath
提供了正确的 node 执行文件,只要在 child_process.option.execPath
指定即可
#
日志说明#
levels- info
- warning 如果没有报错,但是存在警告,一定要warning,前台会展示
- error
- fatal
#
长任务脚本实时输出日志import execa from 'execa'
const subprocess = execa('', { shell: true})
subprocess.stdout.on('data', data => { logger.info({ name: '', detail: data.toString() })})
subprocess.stderr.on('data', data => { logger.error({ name: '', error: { message: data.toString() } })})
caution
像git
或者npm
一些命令,即使error
也只是stdout
,所以要注意处理错误情况