npm create vue@latest 执行过程
1. 引言
目前(2024年3月13日),打开Vue的官网,可以发现其推荐新建一个Vue项目的命令是npm create vue@latest
,为啥这句命令就可以创建一个Vue项目呢
2. 执行过程
根据NPM的命令文档:npm init - npm 中文文档 (nodejs.cn)
npm init <package-spec> (same as `npx <package-spec>) npm init <@scope> (same as `npx <@scope>/create`) aliases: create, innit
可知,npm create vue@latest
等同于npm init vue@latest
,等同于npx vue@latest
根据上面的文档描述
npm init <initializer>
可用于设置新的或现有的 npm 包。在这种情况下,
initializer
是一个名为create-<initializer>
的 npm 包,它将由npm-exec
安装,然后执行其主 bin —— 大概是创建或更新package.json
并运行任何其他与初始化相关的操作。init命令转化为对应的
npm exec
操作如下:
npm init foo
->npm exec create-foo
所以,npm init vue@latest
等同于执行npm exec create-vue@latest
关于npm exec
,命令文档参考:npm exec - npm 中文文档 (nodejs.cn)
npm exec --
[@ ] 此命令允许您在与通过
npm run
运行类似的上下文中从 npm 包(本地安装或远程获取)运行任意命令。如果未提供
-c
或--call
选项,则使用位置参数生成命令字符串。如果未提供--package
选项,则 npm 将尝试根据以下启发式方法从作为第一个位置参数提供的包说明符中确定可执行文件名称:
- 如果包在
package.json
的bin
字段中有一个条目,或者如果所有条目都是同一命令的别名,则将使用该命令。- 如果包有多个
bin
条目,其中一个与name
字段的无范围部分匹配,则将使用该命令。- 如果这不会导致恰好一个选项(或者因为没有 bin 条目,或者它们都不匹配包的
name
),那么npm exec
会以错误退出。
可知,npm exec create-vue@latest
会运行create-vue
包(版本为latest)的package.json
中的bin
字段指定的js文件,如果本地没有create-vue
包则会自动远程获取
那create-vue
包下的bin
是什么呢?
查阅NPM包:create-vue - npm (npmjs.com)
{
"name": "create-vue",
"version": "3.10.1",
"description": "An easy way to start a Vue project",
"type": "module",
"bin": {
"create-vue": "outfile.cjs"
},
// ...
}
可知是"outfile.cjs"
,这个文件是构建之后的代码,不易阅读,如果想要看构建之前的代码,可以查看:vuejs/create-vue: 🛠️ The recommended way to start a Vite-powered Vue project (github.com)
查看这个项目的index.ts
文件,可以知道其实就是根据CMD窗口的提示与输入,创建相应的文件或者文件夹、执行一些命令行代码,例如创建package.json
,README.md
文件等,可参考下面的部分代码
// Supported package managers: pnpm > yarn > npm
const userAgent = process.env.npm_config_user_agent ?? ''
const packageManager = /pnpm/.test(userAgent) ? 'pnpm' : /yarn/.test(userAgent) ? 'yarn' : 'npm'
// README generation
fs.writeFileSync(
path.resolve(root, 'README.md'),
generateReadme({
projectName: result.projectName ?? result.packageName ?? defaultProjectName,
packageManager,
needsTypeScript,
needsVitest,
needsCypress,
needsNightwatch,
needsPlaywright,
needsNightwatchCT,
needsCypressCT,
needsEslint
})
)
console.log(`\n${language.infos.done}\n`)
if (root !== cwd) {
const cdProjectName = path.relative(cwd, root)
console.log(
` ${bold(green(`cd ${cdProjectName.includes(' ') ? `"${cdProjectName}"` : cdProjectName}`))}`
)
}
console.log(` ${bold(green(getCommand(packageManager, 'install')))}`)
if (needsPrettier) {
console.log(` ${bold(green(getCommand(packageManager, 'format')))}`)
}
console.log(` ${bold(green(getCommand(packageManager, 'dev')))}`)
3. 参考资料
[1] CLI 命令 - npm 中文文档 (nodejs.cn)
[2] 彻底弄懂 npm init vue@latest
发生了什么 - 掘金 (juejin.cn)
[3] vuejs/create-vue: 🛠️ The recommended way to start a Vite-powered Vue project (github.com)