20

一份npm命令行全家桶套餐(nvm/nrm/npx)

 3 years ago
source link: https://zhuanlan.zhihu.com/p/260825541
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一份npm命令行全家桶套餐(nvm/nrm/npx)

广发证券 技术工程师

我们知道,下载安装node.js后我们就拥有了npm这一命令行工具。然后只要了解npm install, npm start等简单的命令后,我们就可以愉快的投入开发了。

但如果我们经常在不同的网络环境下工作,或需要同时处理多个依赖node版本不同的项目时,单纯靠npm工作仍然会感到有诸多不便之处,例如:

情况A

我们可能会需要开发多个项目,有的新的项目可能用最新版本的Node进行开发,而有些老的项目因为历史久远,依赖的还是低版本的Node。 如果同时开发这几个项目,且仅靠npm的话,我们就不得不来回下载全局唯一的Node包,这会浪费大量开发时间

情况B

在开发中我们可能经常需要切换npm源,默认的npm源是https://registry.npmjs.org/, 但有时我们会因外墙的原因下载很慢,这时我们可能会切换到淘宝源或者cnpm源。而在另外一些时候,我们可能会需要安装公司内部使用的npm包,这时我们又会切换到公司私有的npm源。我们可以采用npm config set registry --url这样的方式手动切换,但使用却有些不方便,而且众多地址也不利于管理。

情况C

命令行一般要全局安装才能使用,但这有时会“污染”我们的全局环境,有时我们可能会用一些使用频率并不高的命令行,所以希望它即下即用,用完自动删除,而不进行全局环境的安装。

解决方案

这些问题自NPM诞生之初便伴随我们,而随着cli社区的丰富,如今我们已经有足够多的命令行工具可以辅助解决这些问题,它们是——

  • NVM: node版本管理工具,可安装多个版本的node且随时切换,而不必局限于全局唯一的node版本。
  • NRM: node源管理工具,用于简化npm源的切换和查阅
  • NPX: 1.即下即用命令行,避免全局安装 2. 简化终端对node_modules/.bin下文件的执行

它们具体如何使用呢?请看:

以下命令行操作都在Mac上进行,windows会有不同,具体以官方文档为准

一.NVM

安装nvm

1. 在终端运行以下命令安装nvm, 它会被安装到~/.nvm这个路径下

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash

这个时候直接在终端输入nvm可能会报命令找不到的错误

command not found: nvm

2. 这意味着我们需要编辑当前终端的配置文件(如 ~/.zshrc, ~/.bashrc,~/.bash_profile等)

使得每次打开终端的时候都去加载nvm

因为我自己是使用zsh作为自己的终端工具,所以打开 ~/.zshrc文件,并进行编辑

open ~/.zshrc //打开文件

在原来的基础上增加以下内容

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm          

3. 保存该文件,然后关闭终端并重新打开,zsh面板会重新加载 ~/.zshrc配置文件,(或者可以不关闭终端,而通过 source ~/.zshrc命令执行该文件)

4. 运行以下命令查看nvm版本,如果能看到输出就说明成功了

nvm --version   

使用nvm

可通过以下安装某一个版本的node

nvm install 版本       

备注: install后会默认使用该版本的node

安装后,可查看所有已经安装的node版本列表

 nvm ls       

可看到输出中列出了当前安装的所有node,而且用箭头表明了当前正在使用的node

我们可以通过use命令切换当前使用的node版本

nvm use 版本      

如果嫌某个node版本不常用或占位置,我们可以通过uninstall命令删掉它

 nvm uninstall 版本       

二.NRM

因为众所周知的国内网络原因,我们可能会遇到下载某些npm很慢的情况,那么我们可能会修改成淘宝镜像源(或者使用cnpm)。而有时我们会使用公司内部私有的npm包,那么这个时候又要将registry修改为公司内部npm源。修改的方式如下

npm config set registry https://registry.npm.taobao.org
npm config set registry [公司内部npm地址] 

在不同办公情况下,我们可能经常要切换registry,但配置registry的命令稍显冗长,还要我们记住不同的地址,我们想: 有没有简单一些的切换npm源的方式呢?

这个时候,NRM也许是个合适的选择。

安装NRM

运行以下命令安装nrm

npm install -g nrm           
nrm -V

如果有版本输出表示安装成功

使用NRM

1. 通过nrm ls可以查看当前的npm源列表

可以看到nrm默认设置的npm源是官方的npm源,同时也提供了cnpm或者淘宝的npm源

2. 如果需要切换npm源,只需要通过nrm use便可切换

3. 如果要新增npm源(如公司内私有npm源),可通过nrm add添加

例如下面我们添加了一个名为xxx的npm源,其地址为http://registry.xxx.org/ ,然后通过nrm use xxx就可以使用它了

4. 如果想要删除某个npm源,可通过nrm del删除之

三.NPX

和前面介绍的NVM和NRM不同的是,NPX解决的是一些比较细节方面的需求,例如:

  • 用于简化在终端中对node_modules下.bin文件的直接执行
  • 使用某个全局命令行工具时候,下载使用完就自动删除,避免污染全局环境

1.用于简化在终端中对node_modules下.bin文件的直接执行

Taro是一个多端小程序开发框架,它也提供了taro这一cli用于开发和编译,如果试图在终端通过taro命令编译代码,可在项目内部安装taro cli,并进入项目根目录运行:

 node_modules/.bin/taro build --type weapp              

如果你只是想要在终端临时执行命令,而并不想把命令配置到package.json的script字段下,这时可以在终端通过npx进行简化

npx taro build --type weapp
// 等效于: node_modules/.bin/taro build --type weapp          

2.避免污染全局环境

NPX的另外一个作用是过多的全局命令行工具避免污染全局环境。

有很多框架的上手教程里会使用npx来下载脚手架并初始化项目,它们的意思其实是:

“如果你只是下个demo玩一玩的话,就不污染全局环境给你添麻烦了”

例如下面的npx命令,会下载create-react-app并用其初始化my-app项目, 用完就将create-react-app删除。

 npx create-react-app my-app      

npx执行命令 && package.json/script执行命令的区别

相同点:都是先从node_modules/.bin路径下寻找执行文件,然后再从全局寻找命令

不同点

  • 对于npx,当局部和全局都没有找到执行命令会下载安装然后使用
  • 对于package.json下script字段配置的命令,如果没有找到就报错了

实际上,之前我也查阅了和npx相关的资料,知乎上有些讨论说npx是先从全局寻找命令,找不到才再node_modules/.bin下找。

但我在实际验证中得出的结论却是和这相反的,下面展示过程和大家探讨一下 (如有不同意见的话欢迎一起讨论)

这里使用mocha为例: 我在全局安装了8版本的mocha,而在项目下局部安装了6版本的mocha

npm i [email protected] -g  // 全局安装
npm i [email protected]     // 局部安装

通过运行mocha -V和npx mocha -V输出如下

而然后通过npm uninstall把项目局部的mocha卸载掉,npx mocha -V才打印出全局mocha的版本

这说明: npx在执行命令前的搜寻顺序, 是先从node_modules/.bin下找而后才从全局找。如果node_modules/.bin和全局都有同一命令,那么将会使用前者的而不是全局的。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK