通过vue-cli源码学习脚手架

调试 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原型方法 ,打断点调试果然发现这几个名字的函数在原型上都有

相关推荐
恋猫de小郭5 分钟前
Flutter 下 AOT 一个你怎么都想不出来的 Bug ,JIT 正常的计算,在 AOT 居然算错了
android·前端·flutter
晓得迷路了32 分钟前
栗子前端技术周刊第 153 期 - Vitest 5.1、Remix v3.2、Node.js 27 Alpha...
前端·javascript·vite
系统集成-鹰翔1 小时前
ERP单据已作废为什么商品仍不能删除,引用检查与软删除怎么查
javascript·经验分享·后端
Moment1 小时前
Harness Engineering 为什么是 AI Coding 的工程底座 ❓❓❓
前端·后端·面试
头发还在的女程序员1 小时前
基于 Spring Boot + Vue 3 + uni-app 的灵活用工系统:四端架构与业务流程设计
vue.js·spring boot·uni-app·灵活用工·灵工系统
Penge6661 小时前
《Go 后端开发者学 React:Hook》
javascript
Penge6661 小时前
《Go 后端开发者学 React:前端 HTTP 请求详解》
javascript
风骏时光牛马1 小时前
生成一个AI面试复盘标题,只需要一个标题,不需要其他的任何文本。
前端
红尘散仙10 小时前
谁说终端只能敲键盘?我用 Rust 给小说阅读器加上了鼠标
前端·后端·rust