调试 vue-cli 源码
先克隆代码 git clone https://github.com/vuejs/vue-cli.git
,vue-cli
是用 lerna
管理的多package项目。
所以需要先将lerna下载到全局,或者使用 npx
非常方便
npx在不全局安装某些包的情况下,直接运行该包提供的命令行工具,如果已经本地已经存在依赖,直接调用本地的,没有会自动下载安装,使用后自动删除。
执行 npx lerna bootstrap
,它会给我们的lerna项目下载依赖,下载依赖完成,接着切换路径 cd package/@vue/cli
,可以看到下面的 package.json
文件的 bin
出现了 vue
命令,还记得我们之前用vue create 创建项目吗? 然后把这个项目使用 npm link
发布到本地进行调试
如果npm link出现下面的错误 可以切换node@16.13.1试试
*检查npm link是否成功
找到node的位置 mac: which vue
window: where vue
cd到node下的node_modules/@vue,执行 mac: ls
window: dir
查看文件
可以看它是一个软链接,指向的就是我clone下来的文件地址
开始调试 找到bin/vue.js 找到create command,在action添加一行 console.log
打印项目名。
现在使用 create
命令
可以看到它打印了我们的项目名,并且告诉我们的项目名不应该包含大写字母。
如果我们要写一个脚手架需要一些 第三方库
的支持
第三方库
commander
可以用来为脚手架注册命令,看看 vue-cli(bin/vue.js)
是怎么使用的
js
const program = require("commander");
program
.version(`@vue/cli ${require("../package").version}`)
.usage("<command> [options]");
下面具体看看 注册一个命令(command)
需要哪些配置。
举个全面一点的例子
js
const program = require("commander");
program
.version(`@vue/cli ${require("../package").version}`)
.usage("<command> [options]")
.command("create <name> [addition]")//注册create命令
.description("create a new project")
.option("-f, --force [name]", "overwrite target directory if it exist")
.action((name, addition, opt) => {
console.log(name, addition, opt);
});
现在执行 zdzli create project -f 123
打印 project undefined { force: '123' }
执行 zdzli create project -f
打印 project undefined { force: true }
command里的参数默认不传是undefined,option不传默认是false
如果用户输入的命令拼写错误,我们应该提示它正确的拼写,这个时候就需要 program.on
,它的作用是监听命令和选项可以执行自定义函数。看 vue-cli
的实现
js
// output help information on unknown commands
program.on("command:*", ([cmd]) => {//监听任何未知命令
//program.outputHelp();//相当于执行vue --help
console.log(` ` + chalk.red(`Unknown command ${chalk.yellow(cmd)}.`));
console.log();
suggestCommands(cmd);//查找存在的类似单词的方法
process.exitCode = 1;//退出程序
});
suggestCommands
方法我比较好奇是怎么实现的,看到里面引用了第三方库 leven,原理是使用Levenshtein 距离算法测量两个字符串之间的差异。这个算法也叫 编辑距离
在力扣中可以找到,以后有时间可以尝试一下。
另外现在打印自己的 脚手架名字 -h
,Usage 后面默认是index,怎么改成自己脚手架的名字呢,只需要加上 program.name('zdzli(自己脚手架的名字)')
最后还需要执行 program.parse(process.argv);
,至此 bin/vue.js
下的代码差不多都能看懂了。
下面主要就是学习create命令的执行流程了!!!!!!!!!
这个文件(bin/vue.js)里还有统一了错误处理 (不感兴趣可以略过)
点进去看到 enhanceErrorMessages 模块
导出了一个方法
里面重写了 program.Command原型方法
,打断点调试果然发现这几个名字的函数在原型上都有