一、学习调试 vite 源码
我们要学习源码,就避免不了调试代码。正所谓工欲善其事必先利其器。我们先来看看如何使用 vscode 调试 node
- vscode 配置
- 安装
auto-attach插件 cammand(ctrl)+ shift + p,输入auto attach- 点击,然后选择智能模式
- ctrl + shift + ` ,打开
VScode终端。执行npx tsx ./packages/create-vite/src/index.ts
- 安装
- 认识调试按钮

为什么是执行
npx tsx ./packages/create-vite/src/index.ts?我们使用 vite 创建项目时,通常是
npm create vite。那么就要追踪到npm create,npm create在 npm 文档中没有描述。我们可以在终端中执行npm create --help查看一下作用。执行后发现完全等价于npm init。
npm init <initializer>在 npm 文档中是这样解释的。通过执行包名为create-<initializer>下的bin命令,来创建或更新package.json以及执行一些其他的初始化相关操作所以使用 vite 创建项目直接调试 create-vite 包就可以了。
二、第三方依赖
在packages/create-vite/src/index.ts中看到有 4 个第三方依赖:cross-spawn、minimist、prompts、kolorist
分别看下都有什么作用,以及如何使用( <math xmlns="http://www.w3.org/1998/Math/MathML"> 对此部分了解可以跳过 \color{red}对此部分了解可以跳过 </math>对此部分了解可以跳过)
1. prompts:简单易用的CLI提示查询用户信息,node >= 14+
提示函数 prompts 接受两个参数:prompts、options
-
参数一:
prompts- 公共属性
js{ type: String | Function, // type 未 falsy 类型时,该问题不会显示 name: String | Function, // 当前问题结果的 key message: String | Function, // 问题描述 initial: String | Function | Async Function. // 问题默认结果 format: Function | Async Function, // 格式化问题结果 onRender: Function, // 接受 kleur(https://github.com/lukeed/kleur#readme) 作为参数,this 指向当前问题`,`可以通过 kleur 修改 message 样式 onState: Function, // 当前提示更改的回调 stdin: Readable stdout: Writeable }-
属性作为函数类型时函数签名
(prev, values, prompt) => {};,prev前一个 prompt 问题的结果,values当前问题之前所有问题的结果对象,prompt前一个问题对象
- 参数二:
optionsoptions.onSubmit接受三个参数,当前问题,当前问题答案,之前所有问题答案。返回 true,结束所有问题,否则继续options.onCancel与上面相同
- 简单:prompts 被分解成十几个模块,但彼此之间没有太多的依赖,每个都可以独立的完成工作
- 对用户友好:在 cli 界面中提供丰富的色彩和布局
- promise 化:使用 promise 和 async/await,没有回调地狱
- 灵活的:每个 prompts 都是独立的,可以单独使用
- 可测试的:提供编程的方式来提交答案
- 统一的:所有 prompts 提供一致的体验
2. kolorist:将颜色放入标准输入/标准输出的小型库🎉
kolorist API 分为以下几种
- 只以颜色命名的:
red、lightGreen等,都是修改文字颜色 - 以
bg开头 + 颜色:bgRed、bgLightRed等,为文字加上背景色 - 语义化的:
blod、link、underline,这种就是本身语义化的意义 - 自定义色值:
trueColor(255, 255, 255)('输出内容')、ansi256(255)('输出内容')
3. minimist:参数解析
常见用法:
js
import minimist from 'minimist';
var argv = minimist(process.argv.slice(2), options);
console.log(argv);
参数解析规则如下:
- 以 - 加纯英文字母或数字开头加应为字母:-xyz 、-123 、-123a ,-后每个字符都会作为
key,默认value为true - 以 - 加英文字母且以数字结尾:-xyz1 ,只会以
-后紧邻的单个字符作为key,第一个字符后的字符作为该value - 以 -- 加任意数字或英文字母:
- --x4=任意字符 :
=左侧整体会作为key,而右侧作为value - --x4 任意字符 :空格 左侧整体会作为
key,而右侧如果以 - 或者 -- 开头则true作为value,否则空格右侧整体作为value
- --x4=任意字符 :
- 其他所有都会被收录到 _ :[] 中
第二个参数:options
-
{string: ['key']}:如果解析到的key包含在数组中,则其value只能是字符串,如果没有值则是''而不是true -
{boolean: ['key']}:与上同理,不过匹配到value时,不是字符串而是true -
{alias: {a: 'app', b: 'base'}}:匹配到对应key,别名出来映射到配置好的key。输出如下{ _: [], a: true, app: true, b: true, base: true }
-
{default: {a: 'app', b: 'base'}}:如果没有匹配到设置的key,则使用默认值 -
{stopEarly: true}:设置为true后,在第一个不是以 - 开头的元素之后的任何元素都会放到_:[]中- 输入:
node ./packages/create-vite/learn-deps/minimist.js -a 1 b --c=2 - 输出:
{ _: [ 'b', '--c=2' ], a: 1 }
- 输入:
-
{'--': true}:设置为true后,-- 之前所有不是以 - 或 -- 开头元素,都放到_:[]中。-- 之后所有非以 - 或 -- 开头的元素都放到--:[]中- 这里 -- 之前之后,都是指单独 -- 前后直接连接空格
4. cross-spawn:
解决 node 在 window 使用 spawn 的 issue
- 它忽略了PATHEXT。 (PATHEXT window 操作系统中环境变量,用于指定可执行文件扩展名)
- 它不支持shebang。 (shebang 即
#!指定脚本解释器特殊注释,如#!/bin/hash)- 在运行带有空格的命令时会出现问题。
- 在运行带有posix相对路径的命令时会出现问题(例如:./my-folder/my-executable)。
- 在使用命令shims(位于node_modules/.bin/的文件)时,带有引号和括号的参数会导致语法错误。
- 在node <v4.8上不支持options.shell选项。
三、create-vite 逻辑
打开 index.tsx 文件,可以看出前面都在定义变量和函数,最后在执行 init 函数。init 函数逻辑如下图 