持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情
原生脚手架开发痛点分析
痛点一:重复操作
1.多package本地link
2.多package依赖安装
3.多package单元测试
4.多package代码提交
5.多package代码发布
痛点二:版本一致性
1.发布时版本一致性
2.发布后相互依赖版本升级
结论:package越多,管理复杂度越高
lerna简介
lerna是一个优化基于git+npm的多package项目的管理工具
优势
1.大幅减少重复操作
2.提升操作的标准化
\
lerna是架构优化的产物,它揭示了一个架构真理:项目复杂度提升后,就需要对项目进行架构优化。架构优化的主要目标往往都是以效能为核心。
官网
案例
使用lerna管理的大型项目:
1.babel
2.vue-cli
3.create-react-app
lerna开发脚手架流程
核心流程
●命令
○初始化
○发布
○清除缓存
●模型层
○Command命令
○Project项目
○Component组件
○npm模块
○git仓库
●支持模块 utils
○git操作
○云构建
○工具方法
○api请求
用到的技术
●核心库
○import-locale
○commander
●工具库
○npmlog
○fs-extra
○semver
○colors
○user-home
○dotenv
○root-check
拆分原则
按模块的功能拆分:
1核心模块
2命令模块
3模型模块
4工具模块
命令执行流程
- 准备阶段
- 命令注册
- 命令执行
commander示例
const { program } = commander;
program
.name(Object.keys(pkg.bin)[0])
.usage('<command> [options]')
.version(pkg.version)
.option('-d,--debug','是否开启调试模式', false)
.option('-e, --envName <envName>', '获取环境变量名称')
.parse(process.argv);
注册命令
const { program } = commander;
const clone = program.command('clone <source> [destination]')
clone
.description('描述')
.option('-f, --force', '是否强制拷贝')
.action((source, destination, cmdObj) => {
console.log('clone', source,destination, cmdObj.force)
})
监听所有命令
const { program } = commander;
program
.arguments('<cmd> [options]')
.description('描述',{
cmd: 'commnt to run',
options: 'options for command'
})
.action((cmd,options) => {
console.log(cmd,options)
})
命令链接和别名
const { program } = commander;
program
.command('install [name]', 'install package',{
executableFile: 'rd-cli', // 修改脚手架名称
isDefault: true, // true:不去执行其他命令
hidden: true, // 隐藏这个命令
})
.alias('i');
自定义help信息
const { program } = commander;
program.heloInfomation = function(){ return ''} // 将默认的去除
program
.on('--help',function(){
// 自定义
})
实现debug模式
const { program } = commander;
program
.on('option:debug', function(){
if(program.debug){
process.env.LOG_LEVEL = 'verbose'
}
})
对未知命令监听
const { program } = commander;
program
.on('command:*', function(obj){
// 监听
console.log('未知命令:' obj[0])
// 获取所有可用命令
const availableCommands = program.commands.map(cmd => cmd.name())
})