如何打造自己的脚手架
什么是脚手架?
脚手架本质上是操作系统的客户端,能够快速生成项目的目录和底层架构的前端工程化技术。
为什么使用脚手架?
- 能够快速启动项目
- 能够自主选择一些架构功能
- 能够保持项目的统一性
- 可以很好的帮助我们进行技术沉淀
脚手架的实现原理?
通过思考几个问题来理解脚手架的实现的原理,以vue-cli脚手架为例
为什么全局安装 @vue/cli 后会添加的命令为vue?
在@vue/cli/package.json bin 属性指定了 "bin":{ "vue":"./bin/vue.js" }
全局安装 @vue/cli的时候发生了什么
- 将@vue/cli 下载到全局环境下面的node_modules 里面
- 解析 package.json 里面的bin 属性
- 在全局 bin 下面创建软链接
执行vue命令的时候发生了什么
首先了解脚手架有几部分组成(以vue create demo-test --force -r registry.npm.taobao.rog为例)
主命令:vue
Command 子命令 :create
Command 的 param: demo-test
Option : --force 、 -r
Option 的param :registry.npm.taobao.rog
脚手架的执行流程
通过which vue 查看 vue 这个命令执行文件,得出的结果是 /usr/local/bin/vue
这个vue文件是个软连接,通过 ls -al 命令可以查出vue指向的文件地址,也就是 ../lib/node_moduels/@vue/cli/bin/vue.js
文字总结:
-
终端输入 命令 vue create demo-test --force -r registry.npm.taobao.org
-
终端解析 vue 命令 ,并找到执行文件
-
利用node 执行 vue.js 文件
-
vue.js 解析 command/option
-
vue.js 执行 command/option
-
脚手架执行完毕
为什么vue指向一个js文件,我们却可以直接通过vue命令去执行它?
在文件头部加入 注释
#!/usr/bin/env node
告诉系统在环境变量中寻找node 来执行此文件。所以 vue.js 就可以直接运行。不用写 node vue.js
开发脚手架包基本的目录结构是什么?
无法复制加载中的内容
如何注册脚手架命令
package.json 文件里面配置bin 属性
"bin": {
"butterfly-mp-cli": "bin/index.js" //脚手架核心文件
}
如何进行本地调试
在项目目录下面执行 npm link ,就能在本地添加了 butterfly-mp-cli 命令。项目发布之后记得npm unlink 取消发布
如何发布脚手架
npm login
npm publish
如何进行多包调试?
创建依赖库项目
{
"name": "butterfly-mp-lib",
"version": "1.0.0",
"description": "butterfly-mp-cli 库文件",
"main": "lib/index.js", // 指定核心文件
"directories": {
"lib": "lib"
},
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"author": "",
"license": "ISC"
}
npm link 后就可以在cli 项目通过手动配置 就能访问到库文件
"devDependencies": {
"butterflu-cli-lib": "^1.0.0"
}
如何进一步完善自己的脚手架
一个完整的脚手架应该包含如下部分
- 注册脚手架子命令(command)
- 注册子命令配置(option)
- 能解析option 的 param
- 复杂脚手架能运用分包
- 能提供帮助文档
- 能进行命令行的交互
- 能打印日志
- 能处理文件
要想实现以上的功能我们就要借助个脚手架开发库yargs,来一点点帮助我们完善脚手架。
#!/usr/bin/env node
const yargs = require('yargs/yargs')
const { hideBin } = require('yargs/helpers')
const dedent = require('dedent')
const argv = hideBin(process.argv)
const cli = yargs(argv)
cli
.strict() // 严格模式
.alias('h', 'help') //缩写
.alias('v', 'version')
.wrap(cli.terminalWidth()) //设置输出宽度
.epilogue(dedent`这是商城小程序脚手架`) // 尾部添加注释
.demandCommand(
1,
'A command is required. Pass --help to see all available commands and options.'
)
.options({
debugger: {
type: 'boolean',
describe: 'Dev Debugger',
alias: 'd',
},
log: {
type: 'string',
alias: 'l',
describe: '这是日志',
},
}) // 添加options
.option('console', {
type: 'string',
describe: '这是console',
alias: 'c',
}) // 添加option
.group(['help', 'version'], 'Global Options') // 将options 分组
.command(
'init [name]',
'Do init',
(yargs) => {
yargs.options({
name: {
type: 'string',
describe: 'The project name',
alias: 'n',
},
})
},
(argv) => {
console.log(argv)
}
)
.command({
command: 'create',
aliases: ['c'],
builder: (yargs) => {
yargs.option('name', {
alias: 'n',
describe: 'The name',
type: 'string',
})
},
handler: (argv) => {
console.log(argv)
},
})
.recommendCommands() //校验提示命令
.fail((err, msg) => {
// 输入错误定制信息
console.log('err', err)
console.log('msg', msg)
}).argv
最终效果:
yargs使用总结:
- strict() 使用严格模式
- alias() 使用别名
- wrap() 控制输出的文字宽度
- options() 以对象的方式添加options
- command() 添加主命令
- option() 单个添加option
- group() 将option分组
- recommendCommands() 校验命令并给出提示
- fail() 命令输出错误的回调函数
如何对项目进行多package 管理
Lerna 简介
Lerna 是一个优化基于git+npm 的多package项目管理工具。Lerna 是架构优化的产物,它解释了一个架构真理;项目复杂度提升后,就需要对项目进行架构优化,架构优化的主要目的往往都是以效能为核心。
lerna解决了那些痛点?
-
重复操作的步骤
- 多package 本地link
- 多package 依赖安装
- 多package 单元测试
- 多package 代码提交
- 多package 代码发布
-
版本一致性
- 发布时版本一致性
- 发布后相互依赖版本升级
如何使用Lerna 开发脚手架
安装lerna
npm install lerna -g
了解lerna命令
- lerna publish
- lerna version
脚手架代码更新后,可以用来升级脚手架版本。
- lerna bootstrap
给每个package添加添加所有依赖
- lerna list
- lerna changed
- lerna diff
- lerna exec
Lerna exec -- rm -f node_modules 在每个package里面执行shell 命令
- lerna run
执行每个package下面的npm 命令
- lerna init
- lerna add
给每个package添加依赖
- Lerna clean
请空package下面点node_modules 包依赖
- lerna import
- lerna link
给package之间的相互依赖添加link
- lerna create
Lerna create 创建一个新的packgae包
- lerna info
开始使用
- 创建脚手架文件夹 butterfly-mp-cli-test
- 初始化npm npm init
- 初始化lerna lerna init
- 创建核心包cli lerna create cli
- 创建的时候将 包名命名为 @butterfly-mp-cli-test/cli(@butterfly-mp-cli-test npm 组织名)
- 在cli包里面按照上面讲的配置脚手架命令 bin:{'butterfly-mp-cli-test': 'bin/index.js'}
- 在项目根目录 添加LICENSE.md (开源声明文件)
- 在cli包 package.json 添加 "publishConfig": {"access": "public"} 将包设置为公开类型
- 最后 发布 lerna publish
总结
可以通过lerna 框架和实现部门npm库的搭建和管理,通过yargs 来实现和完善项目脚手架。