You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Windows
PS C:\Users\ziyi2\Desktop\npm-cli-package>npmlinkuptodatein0.428s
C:\Users\ziyi2\AppData\Roaming\npm\npm-cli-package->C:\Users\ziyi2\AppData\Roaming\npm\node_modules\npm-cli-package\src\index.js
C:\Users\ziyi2\AppData\Roaming\npm\node_modules\npm-cli-package->C:\Users\ziyi2\Desktop\npm-cli-package// MAC OS XAppledeMacBook-Pro:npm-cli-packageziyi2$npmlinknpmnoticecreatedalockfileaspackage-lock.json.Youshouldcommitthisfile.uptodatein4.113sfound0vulnerabilities/usr/local/bin/npm-cli-package->/usr/local/lib/node_modules/npm-cli-package/src/index.js/usr/local/lib/node_modules/npm-cli-package->/Users/ziyi2/Git/npm-cli-package
前言
在项目中我们经常会用到一些Node脚本命令来简化开发的工作量,例如Element的
package.json
的npm 脚本命令build:file
(使用脚本生成Webpack的入口源文件)。简单的Node脚本命令可以解决当务之急,但是如果该Node脚本实现的功能相对复杂繁多,并且多人使用同一个脚手架生成的多个项目里有相同的Node脚本,则可能会产生以下问题:为了解决Node脚本命令产生的上述问题,可以采用NPM发布命令行(CLI)工具(具体可查看Creating and publishing unscoped public packages)的形式实现Node脚本命令的功能。
NPM包管理器
NPM包管理器允许用户将自己编写的包或命令行工具上传到NPM服务器,开发人员只需要从NPM服务器下载并安装该命令行工具到本地即可使用。命令行工具可以通过更新NPM服务器上的命令行程序版本进行远程升级,开发人员可以再次通过NPM服务器更新命令行工具的版本进行工具升级。
发布的命令行工具可以实现本地项目依赖安装和全局安装两种方式。采用本地项目依赖安装会将发布的命令行工具加入到项目的开发态依赖列表,这不能解决项目依赖增加的问题,如果需要解决该问题,可以采用全局方式安装,从而将NPM命令行工具的命令链接到全局执行环境(此时Node脚本不会植入到项目中,而是存放在操作系统的用户文件夹中),实现命令行工具的全局使用。
这里列举几个常见的命令行工具:
构建、发布和使用命令行工具
构建命令行工具
首先新建NPM命令行工具的项目文件,使用
npm init
命令创建package.json
命令行工具的描述文件,创建后的package.json
包含项目名称、版本、描述、项目入口文件(在发布命令行工具时并不需要main
字段信息,该信息主要用于发布依赖包而不是命令行工具)、作者信息等。执行npm init
:执行完后生成的
package.json
描述文件如下:其次NPM命令行工具需要配置在PATH路径下的可执行文件,在
package.json
里配置一个bin
属性,该属性对应的是可执行文件的路径(当使用npm link
或者全局安装命令行工具时,NPM会为bin
中配置的文件在bin
目录下创建一个软连接,对于Windows系统,默认会在C:\Users\{username}\AppData\Roaming\npm
目录下,若是局部安装则会在项目的./node_modules/.bin
目录下创建一个软连接)。例如将
bin
对应的可执行文件路径配置为当前项目下的src/index.js
:配置
bin
属性的模块路径后,可以开始设计可执行文件。为了使入口文件使用Node作为解释程序,需要在入口文件的头部写入#! /usr/bin/env node
,目的是使用env来寻找操作系统中的Node启动路径,并将Node作为程序的解释器(在env中包含了一些环境变量,包括我们安装的一些环境的路径等。在不同的操作系统中,我们安装Node的路径可能会有所不同,但是其环境变量会存在于env中,这里我们使用env来找到Node的执行路径。因此env的主要目的就是让我们的脚本在不同的操作系统上都能够正常的被解释和执行)。例如在src/index.js
入口文件写入一个打印信息的Node脚本:NPM软链接
命令行工具构建完成后,接下来是测试该命令行工具能否被正常使用,此时可以通过
npm link
命令将NPM命令行工具链接到全局执行环境,从而在系统的任意路径下都可以使用该NPM命令行工具。执行npm link
:当执行
npm link
后,可以看到在Mac系统下该命令主要做了两件事:package.json
文件的bin
属性所配置的可执行文件src/index.js
)创建一个软链接,将其链接到/usr/local/bin/<package>
(Windows下是C:\Users\{username}\AppData\Roaming\npm\<package>
)/Users/ziyi2/Git
的npm-cli-package
文件目录中)创建一个软链接,将其链接到/usr/local/lib/node_modules/<package>
(Windows下是C:\Users\{username}\AppData\Roaming\npm\node_modules\<package>
)因此在全局环境执行
<name>
命令时(pageage.json
中的name
字段,默认如果bin
不配置执行的命令名称时,使用name
字段作为命令,这里演示中将执行的命令名称配置成了npm-cli-package
),会启用Node去执行package.json
中bin
字段对应的可执行文件,此时可在任意位置执行npm-cli-package
命令:可以发现在当前项目外的任意路径都可以使用该命令成功打印信息,说明Node解释器和软链接都设置成功。Windows系统可以到用户目录
C:\Users\{username}\AppData\Roaming\npm\node_modules
下查看npm-cli-package
包的软链接,并且可以在C:\Users\{username}\AppData\Roaming\npm
中找到npm-cli-package
(Shell)和npm-cli-package.cmd
(Cmd)两个可执行文件。在真正设计CLI工具时,你可能需要一些额外功能的依赖,例如:
发布NPM命令行工具
通过
npm link
以及命令行的使用测试,发现命令行工具没有任何问题,此时想将该工具分享给他人使用,可以利用NPM包管理器的发布机制。在发布命令行工具之前,需要在NPM官网注册账号(需要设置邮箱并进行邮箱),注册成功后,在命令终端中使用npm login
链接你注册的账号(npm login
会将账号登录的证书信息保存在本地电脑,从而不需要再次登录账号),同时会在npm的网站中生成你当前登录的token信息,登录后可以通过npm whoami
命令查看当前登录账号名。注意登录的时候不要使用NPM淘宝镜像地址,需要使用NPM官方地址,可以通过npm config set registry https://registry.npmjs.org/
命令设置成NPM官方的包发布地址。。npm login
后会在npm官网产生token信息。使用
npm publish
命令发布命令行工具:此时查看NPM官网中的个人账号信息,可以发现发布了该命令行工具的
1.0.0
版本。如果需要发布Scope包,需要在NPM官网中创建一个组织(例如这里将ziyi222的账号作为组织,然后将账号ziyi222重命名成ziyi222222,并重新登录账号):
重新修改
package.json
配置文件:使用
npm publish
发布:命令行工具下载安装和使用
开发者可以通过
npm install
命令对命令行工具进行全局安装:由安装打印信息可以发现,最终命令行工具脚本链接指向了
/usr/local/bin/npm-cli-package
。安装成功之后,可以在项目中使用命令行工具指定的命令。总结
命令行工具如果有功能需要扩展,可以再次通过
npm publish
命令发布新版本的NPM包,此时其他开发者可以通过npm install
全局安装的形式进行工具升级,因此使用发布NPM包的形式可以使命令工具的版本升级和维护更方便。参考文献
The text was updated successfully, but these errors were encountered: