1、npm run dev会启动根目录下的package.json里的scripts字段指定的命令。
所以执行npm run dev等同于执行vite(仅限于下图场景中)
2、npm会到node_modules/.bin/目录下找到vite.sh,并执行该shell
该shell文件如下
#!/bin/sh
# $0 代表脚本自身的路径
# dirname 获取脚本所在的目录路径
# sed -e 's,\\,/,g' 将路径中的\替换为/ ,确保不同系统路径格式统一
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
# 若环境为windows,将 basedir 转换为 Windows 风格的路径
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
# 执行"$basedir/../vite/bin/vite.js"
# "$@"表示将命令行给脚本的参数传递给 vite.js
if [ -x "$basedir/node" ]; then # 如果该路径下有node
exec "$basedir/node" "$basedir/../vite/bin/vite.js" "$@"
else
exec node "$basedir/../vite/bin/vite.js" "$@"
fi
大致意思是,找到node_modules/vite/bin/vite.js并执行。但是做了不同系统的兼容和不同node的选择。
3、那找到该vite.js后,node会执行该文件。
#!/usr/bin/env node
import { performance } from 'node:perf_hooks'
if (!import.meta.url.includes('node_modules')) {
try {
// 开发环境下启用源码映射
await import('source-map-support').then((r) => r.default.install())
} catch (e) { }
}
// 将当前时间(ms)存储在全局变量里,便于后续性能分析
global.__vite_start_time = performance.now()
// debugIndex: 查找是否存在 -d 或 --debug 参数,用于启用调试模式
// filterIndex: 查找是否存在 -f 或--filter 参数,用于过滤调试日志
// profileIndex:查找是否存在--profile 参数,用于性能分析
const debugIndex = process.argv.findIndex((arg) => /^(?:-d|--debug)$/.test(arg))
const filterIndex = process.argv.findIndex((arg) =>
/^(?:-f|--filter)$/.test(arg),
)
const profileIndex = process.argv.indexOf('--profile')
// 如果存在 -d 或 --debug 参数,提取其值(如 vite:*),并将其添加到 DEBUG 环境变量中。
// DEBUG 是一个常用的环境变量,用于控制调试日志的输出。
if (debugIndex > 0) {
let value = process.argv[debugIndex + 1]
if (!value || value.startsWith('-')) {
value = 'vite:*'
} else {
// support debugging multiple flags with comma-separated list
value = value
.split(',')
.map((v) => `vite:${v}`)
.join(',')
}
process.env.DEBUG = `${process.env.DEBUG ? process.env.DEBUG + ',' : ''
}${value}`
// 如果存在 -f 或 --filter 参数,提取其值并存储在 VITE_DEBUG_FILTER 环境变量中,用于进一步过滤调试日志。
if (filterIndex > 0) {
const filter = process.argv[filterIndex + 1]
if (filter && !filter.startsWith('-')) {
process.env.VITE_DEBUG_FILTER = filter
}
}
}
// 动态导入 Vite 的 CLI 入口文件,vite核心所在
function start() {
return import('../dist/node/cli.js')
}
// 启用性能分析
if (profileIndex > 0) {
process.argv.splice(profileIndex, 1)
const next = process.argv[profileIndex]
if (next && !next.startsWith('-')) {
process.argv.splice(profileIndex, 1)
}
const inspector = await import('node:inspector').then((r) => r.default)
const session = (global.__vite_profile_session = new inspector.Session())
session.connect()
session.post('Profiler.enable', () => {
session.post('Profiler.start', start)
})
} else {
start()
}
所以,npm run dev = node .\node_modules\vite\bin\vite.js
问题:既然npm run dev等于执行vite,为什么控制台执行vite会报错?
答:因为vite没有在系统环境变量里。当将node_modules/.bin/
添加到 PATH
就可以成功执行;或者全局安装vite。
所以就是,npm run dev ---> vite ---> /node_modules/.bin/vite ---> vite.js ---> cli.js(vite核心)
绕这么大一圈,是为了不同系统的兼容、固定的命令(便于开发者)、支持非全局vite(版本隔离)!