前言
前阵子在 Vite 文档 看到快速构建 Vite 工程的命令:
npm create vite@latest
第一次见过 npm create
命令,查阅后发现是 npm init
的别名,上面的命令等效于:
npm init vite@latest
不过,我之前也没见过 npm init
的这种用法。上面的命令猜测应该是下载并执行了 Vite 工程里的项目创建命令,这种执行远程命令的方式,我只知道 npx
,比如 React 项目创建:
npx create-react-app my-app
看来,是我小看 npm init
了。于是,翻阅了一下文档,做个总结。
创建一个简单的 npm 包
执行命令
npm init
会询问用户几个问题,npm 根据用户的回答生成一个 package.json
文件。带有 package.json
文件的目录是一个 npm 包,这个命令也就是用于创建一个 npm 包。
选项 -y/--yes
可以跳过问题,使用默认值生成 package.json
。
如果你喜欢,手动创建 package.json
也是一样的效果。
指定初始化命令创建定制化包
在 npm 提供了 npx 之后,也拓展了 npm init
的能力:可以通过指定命令,创建一些特定结构的包。
npm init <initializer>
需要注意的一点是,<initializer>
指定的包名是 create-<initializer>
。npm 会自动去找 create-<initializer>
包,如果本地不存在,就会从远程下载,并执行其 bin
目录下的主命令,这个命令一般用于修改当前这个包的结构和配置,即初始化操作。
仍然以 npm init vite
为例,执行命令,可以看到提示:
Need to install the following packages:
create-vite@3.2.0
Ok to proceed? (y)
它会下载 create-vite
并执行其中的命令,这个命令为我们创建一个 Vite 应用。
类似,可以这样使用 create-react-app:
npm init react-app my-app
# 同 npx create-react-app my-app
init
命令语义更简洁一点,不过也提出了一个限制:这类包名必须以 create-
开头。像 typescript-starter 这种包不得不使用 npx 了。
对命名空间下的包,解析规则稍有不同:
npm init @foo # npx @foo/create
npm init @foo/bar # npx @foo/create-bar
此外,yarn init
也支持同样的功能。
并非空目录下才能使用 npm init
最后纠正一个大部分人可能有的误解,npm init
并不是只有在项目初始化时才能使用。即使是在一个已有的包,你也可以使用它。
对于不指定包的 npm init
,文档的说明是:
It is strictly additive, so it will keep any fields and values that were already set.(它是添加性操作,所以已有的字段和值都会保留下来)
如果指定了用于初始化的命令,就取决于包的作者了。比如, @eslint/create-config 就是增量式的修改。
利用这点,一些软件工具的作者可以让用户很方便地引入自己的软件。比如,ESLint 的首页就有一个快速开始的命令:
npm init @eslint/config
看到这里,你应该对这个命令很了解了。用户可以使用它快速引入 ESlint,即使这并不是一个新项目。
总结
- 简单的
npm init
可以用于创建一个 npm 包,它会在当前目录下生成一个package.json
文件。 npm init <initializer>
会执行create-<initializer>
包中的命令作为初始化操作,可以用于创建具有特定结构的 npm 包。npm init
可以在已有的包中执行,引入增量内容。