彻底弄懂 `npm init vue@latest` 发生了什么

7,674 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 22 天,点击查看活动详情

start

  • 最近在看 vue3 官方文档 ,vite 官方文档的时候 ,官方提供了这么几个命令用来初始化项目:
# vue3
npm init vue@latest

# vite
npm create vite@latest
  • 除此之外,这几天看vue-cli官方文档,顶部突然就有这么一句警告:“现在官方推荐使用 create-vue 来创建基于 Vite 的新项目。”
  • 为何现在初始化项目都看不懂了?
  • why?
  • 今天就带大家彻底弄清楚这些命令。

历史知识:

可能很多小伙伴和我类似,知道可以使用 npm init 用来初始化我们本地项目的 package.json,然后根据提示,输入项目名,作者名等配置。

当然还可以使用 npm init -y 来实现跳过手动配置,一键初始化本地项目。

例如:

image.png

开始研究

前言

  1. npm 的官网:www.npmjs.com/

  2. 最近在研究 npm 相关的知识,我总结起来主要围绕两点:

    • package.json的属性;
    • npm 相关的内置命令;

npm create

俗话说的好,犹豫不决就看官方文档:docs.npmjs.com/cli/v6/comm…

我找遍了npm的 v6,v7,v8版本官方文档,居然没有 npm create 这个命令。

虽然看到 create 单词,可以猜测这个命令是创建的意思,但是没有官方文档,暂不能下定论。

image-20220818201133965.png

随即搜索了相关知识,看到有人提到,虽然官方文档没有明面上体现npm create。但是可以在github上的npm-v6的 CHANGELOG 中找到答案。 随即又翻阅了github上的 CHANGELOG 找到了相关说明。https://github.com/npm/cli/blob/v6/CHANGELOG.md

image-20220818200849859.png

机器翻译:

感谢@jdalton的努力,现在npm init可以用来调用自定义脚手架工具了!

你现在可以分别通过运行create-react-app和create-esm来做npm init react-app或npm init esm来搭建一个npm包。这也增加了一个npm create别名,以对应Yarn的Yarn create特性,这启发了我们。

添加一个npm初始化特性,当使用位置参数调用npx时调用它。

总结:

npm createnpm init的别名。。。。

npm init

所以重点就在于 npm init这个命令什么作用:docs.npmjs.com/cli/v6/comm…

image-20220818203102254.png

1.我们先看看顶部的概要:

原文:

Synopsis(概要)

npm init <package-spec> (same as `npx <package-spec>)
npm init <@scope> (same as `npx <@scope>/create`)

# aliases: create, innit

总结: 由上可得:

  • npm init 包名 类似于 npx create-包名

  • npm init @包名 类似于 npx @包名-create

  • 好吧,官方在这里体现了create这个命令 :init 别名: create, innit

2.init详细解释

继续向下阅读:(浏览器翻译)

image-20220818232726290.png

// 我自己意译的:

`npm init <initializer>` 可以建立新的或者现有的npm包;

`initializer`在 npm init 后面出现的这种情况下,可以把它理解为名称为 `create-initializer`的npm包将由 npm-exec,去执行其对应的 .bin 中的文件,然后做一些操作

总结:

  • npm init <initializer> 可以理解为 npx create-initializer;
  • npm exec 这个需要注意一下,和 npx类似,但是对于后续的传参的处理有所不同(这里可以理解就是 npx)

3.基础npm init

后续的内容:

If the initializer is omitted (by just calling npm init), init will fall back to legacy init behavior. It will ask you a bunch of questions, and then write a package. json for you.


// 我意译的:
如果没有在 npm init后续添加参数,及理解为历史的 npm init功能。用来初始化项目的 `package.json`

总结:

  • 这里就是对我们熟知的内容,做了说明。

解释开头的问题

1.开始执行

npm init vue@latest

2.理解一下 init 命令

由上述的 init详细解释 可得:

npm init vue@latest
# 
npx create-vue@latest

3. @latest 怎么理解?

这地方暂时使用了 install命令的解释

官方解释: docs.npmjs.com/cli/v6/comm…

npm install sax@latest

# Install the version of the package that is referenced by the specified tag. If the tag does not exist in the registry data for that package, then this will fail.
# 安装指定版本的包。如果版本尚未发布到注册表,这将失败。

为了验证文档所说的,我在npm库中搜索了这个包,查看了它的版本, 链接:www.npmjs.com/package/cre…

image.png

  1. 存在 @latest版本的包,版本号:3.3.2
  2. 周下载量暂时不高 14444

4. npx使用逻辑

npx作用:调用项目内部安装的模块。

npx会先验证本地是否安装了该软件包,安装了则直接使用该软件包。如果未安装将读取远程库中的create-vue,并缓存到全局的npm-cache中。

有关npx的详细说明可以查看官网:docs.npmjs.com/cli/v7/comm…

细节提示:

# 获取 npm-cache 的路径
npm get config cache

验证的截图: image.png

image.png

5.开始执行

npx 执行的是可执行的脚本,这个脚本哪里来,就需要看 create-vue 中的 package.jsonbin 属性;

create-vue package.json image.png

当下载 create-tomato 的时候,会根据 create-tomato 项目中 package.jsonbin 对象中的属性创建可执行文件,bin中的属性名,就是执行文件的名称。对应的属性值,为对应的本地文件路径。

三个文件只是后缀不同,作用相同,只是用来兼容不同的系统

node_modules\.bin image.png

总结:

简单来说,npx create-vue =》 就是在执行 create-vue 项目的 outfile.cjs 文件 (.cjs 意思是 CommonJS规范)

image.png

6. create-vue 中的 outfile.cjs

我们初始化项目会提示我们选择配置,这些提示配置就都是根据这个 outfile.cjs 文件来的。

初始化项目的时候展示的提示: image.png

浅读一下 outfile.cjs,文件很长。4000多行,而且还是打包过后的代码,这里我们看我们看得懂的地方。

outfile.cjs源码截图 image.png

总结

  1. npm createnpm init 的别名;

  2. npm init 除了我们熟知的初始化 package.json,还可以利用远程库来初始化项目;

  3. npm init tomato 可以理解为: 执行create-tomato》package.json》bin》create-tomato》outfile.cjs

end

  • 时间有限,若有错误之处欢迎指正。
  • 加油