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.jsonbin 字段中有一个条目,或者如果所有条目都是同一命令的别名,则将使用该命令。
  • 如果包有多个 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.jsonREADME.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)

posted @ 2024-02-29 23:14  当时明月在曾照彩云归  阅读(179)  评论(0编辑  收藏  举报