1. 脚手架实现原理,基于 Lerna 搭建自己的脚手架并发布到npm
1.1 为什么全局安装 @vue/cli 后会添加的命令为 vue ?
全局安装脚手架后,会根据脚手架的 package.json 中的 bin 来决定脚手架的命令
"bin": {
"vue": "bin/vue.js"
},
当执行vue命令的时候,相当于执行node bin/vue.js
1.2 全局安装 @vue/cli 时发生了什么
首先 npm 下载包文件到 node 安装目录下的 node_modules,然后根据 package.json 文件 bin 属性中配置的命令在 C:\Program Files\nodejs 生成一个 vue 文件并注册到环境变量
1.3 执行 vue 命令时发生了什么?为什么 vue 指向一个 js 文件,我们却可以直接通过 vue 命令去执行它呢?
因为会在 bin/vue.js 文件头部声明了以下代码
#!/usr/bin/env node
它会告诉系统要用 node 去执行
1.4 已发布到npm脚手架 diao-cli
2. Yargs 常用 API 和开发流程
const yargs = require('yargs/yargs')
// 一个ES6字符串标签,从多行字符串中去除缩进。
const dedent = require("dedent");
const cli = yargs()
const argv = process.argv.slice(2)
// 注入额外参数
const context = {
diaoVersion: '1.0.0',
};
cli
// 开启严格模式,输入无效命令会报错无法识别命令
.strict()
// 在头部输出一段信息
.usage('Usage: diao-cli [command] <options>')
// 设置需要输入命令的最小值,这里设置最少输入一个命令,否则则抛出错误信息
.demandCommand(1, "A command is required. Pass --help to see all available commands and options.")
// 如果没有找到匹配的命令,yargs提供关于类似命令的建议
.recommendCommands()
// 在有错误的时候执行,可以在这里自定义错误信息
.fail((err, msg) => {
console.error('err:', err)
})
// 设置 command 的别名
.alias('h', 'help')
.alias('v', 'version')
// 设置命令行输出时候的宽度
.wrap(cli.terminalWidth())
// 在命令行末尾打印的消息
.epilogue(dedent`
When a command fails, all logs are written to lerna-debug.log in the current working directory.
For more information, find our manual at https://github.com/lerna/lerna
`)
// 配置额外选项
.options({
debug: {
type: 'boolean',
describe: 'Bootstrap debug mode',
alias: 'd'
}
})
// 配置额外选项
.option("registry", {
type: "string",
describe: 'Define global registry',
alias: 'r'
})
// 对选项进行分组
.group(['debug'], 'Dev Options')
.group(['registry'], 'Extra Options')
// 注册命令
.command('init [name]', 'Do init a project', (yargs) => {
yargs
.option('name', {
type: 'string',
describe: 'Name of a project',
alias: 'n'
})
}, (argv) => {
console.log(argv)
})
// 注册命令
.command({
command: 'list',
aliases: ['ls', 'la', 'll'],
describe: 'List local packages',
builder: (yargs) => {},
handler: (argv) => {
console.log(argv)
}
})
// 解析命令输入参数
.parse(argv, context)
3. Lerna 常用命令和实现原理
Lerna 是基于 git+npm 的多package项目管理工具
3.1 常用命令
初始化 Lerna 项目
lerna init
创建 Package
lerna create @diao-cli/core packages
安装依赖
lerna add mocha packages/core --dev
删除依赖
lerna clean
安装依赖
lerna boorstaap
执行单元测试
lerna run test
执行特定包单元测试
lerna run test @diao-cli/core
link 项目
lerna link
发布项目
lerna publish
3.2 Lerna 实现原理 (需要二刷三刷)
- 通过 import-local 优先调用本地 lerna 命令
- 用过 Yargs 生成脚手架,先注册全局属性,再注册命令,最后通过 parse 方法解析参数
- lerna 命令注册时需要传入 builder 和 handler 两个方法, builder方法用于注册命令专属的 options,handler 用来处理命令的业务逻辑
- lerna 通过配置 npm 本地依赖的方式进行本地开发,具体写法是在 package.json 的依赖中写入:fill:your-kicak-module-path,在 lerna publish 时会自动将该路径替换
4. 理解 import-local 实现原理, 理解 require.resolve 实现原理
懵逼中,后面回过头再看~