npm可以把包安装到全局,也可以安装到本地,但是对于工具类的包通常是在命令行中作为命令使用,如果不安装到全局的话,则在执行相应工具的命令时必须加上命令的路径,很不方便;如果安装到全局的话,对于像我这样有强迫症的人是很不喜欢把乱七八糟的东西放在系统级目录下的;为了解决这个问题,我研究了几个方案,通过这几个方案均能实现即不把包安装到全局,又能在命令行中方便地使用;如下:
背景知识
1. 命令的查找目录
(详情请参考《Shell终端命令行的重点知识》)
当在终端直接输入命令时,如:guobinyongMac:~ guobinyong$ ls
,系统会在一些指定的目录中查找相应命令的可执行文件,然后执行查找到的可执行文件;如果命令的可执行文件不在默认的目录中,则需要在输入命令时写出命令的路径,如:
假设我需要执行命令gby,而gby文件在目录./PATH/
下,则需要这样输入命令:
guobinyongMac:~ guobinyong$ ./PATH/gby
这样是不太方便的,如果不想输入命令的路径,则可以把命令的所在目录配置为终端的命令查找目录;
如何配置呢?通过PATH变量!
PATH变量中保存的是命令查找路径的列表,目录之间用冒号 :
分隔;配置方法如下:
在终端的配置文件~/.bash_profile
(如果不存在,则创建该文件)中添加如下代码:
export PATH=$PATH:新的路径 //把您要添加的路径写在$PATH:后面
2. 目录前缀配置参数prefix
(详情请参考《npm常用技巧》)
prefix参数指定全局安装时相关目录的共同路径,即全局安装的根目录;
可以通过如下命令配置prefix参数:
npm config set prefix <路径> [-g|--global] //给配置参数key设置值为value;
配置prefix参数后,当再对包进行全局安装时:
包会被安装到如下位置:
Unix系统:{prefix}/lib/node_modules
Mac系统:{prefix}/lib/node_modules
Windows系统:{prefix}/node_modules
并且,会把可执行文件链接到如下位置:
Unix系统:{prefix}/bin
Mac系统:{prefix}/bin
Windows系统:{prefix}
手册页会被安装到如下位置:
Unix系统:{prefix}/share/man
Mac系统:{prefix}/share/man
Windows系统:在Windows系统中也不会安装手册页;
注意:
Mac系统也属于Unix系统,所以Mac系统的安装路径与Unix系统一样;
方案1:配置npm的目录前缀配置参数prefix
此方案的思路:
更改npm全局安装的路径为路径A,然后再把路径A添加到终端的命令查找路径列表中;
具体操作如下:
- 创建全局包的安装目录pathG;
- 配置npm的目录前缀配置参数prefix的值为自定义的目录pathG;
guobinyongMac:~ guobinyong$ npm config set prefix pathG
- 把自定的目录中的可执行文件的路径添加到终端的命令查找目录列表中;
因为全局安装的包的可执行文件会被自动链接到pathG/bin目录下,所以要把pathG/bin目录添加为终端的命令查找目录,具体配置为:
在终端的配置文件~/.bash_profile
(如果不存在,则创建该文件)中添加如下代码:export PATH=$PATH:pathG/bin
- 重启终端;
此方案的优点:
- 在任何目录下都可以把包安装到此方案配置的目录中,只需要在安装命令中加上全局选项
-g
;- 可以安装手册页;
此方案的缺点:
- 此方案替换了npm默认的全局安装方案(与方案2相比);
- 当更新npm时,新版本的npm也会被安装到配置的目录中;并且不会覆盖在系统目录下的npm;
方案2:配置命令查找路径PATH为指定目录
此方案的思路:
把包以本地安装的方式安装到一个目录中,然后把包的安装目录添加进终端的命令查找路径中;
具体步骤如下:
- 创建安装包的目录;
- 以本地安装的方式安装相应的包;
guobinyongMac:~ guobinyong$ npm install 包名
- 给终端添加命令查找目录:
因为本地安装的包的可执行文件会被自动链接到node_modules/.bin目录下,所以要把node_modules/.bin目录添加为终端的命令查找目录,具体配置为:
在终端的配置文件~/.bash_profile
(如果不存在,则创建该文件)中添加如下代码:export PATH=$PATH:安装目录/node_modules/.bin
- 重启终端;
此方案的特点(不是优点):
- 此方案安装的包是本地包,不是全局包;即可以以全局包的使用方式使用本地包;
此方案的优点:
- 此方案不会覆盖全局安装方案,即不会更改全局安装的配置,相当于给npm又提供了一种新的安装方案;
- 有package.json文件,在更换电脑时,方便恢复安装包;
- 不影响npm的更新;
此方案的缺点:
- 只能在此方案配置的目录下安装包;
- 不会安装手册页;
方案3:配置命令查找路径PATH为项目目录
此方案的思路:
因为对于本地安装的包的可执行文件会被链接到项目目录下的 node_modules/.bin/
目录下,而Shell变量PWD中保存的是当前目录,所以可以动态地配置终端的查找路径为当前项目下的 node_modules/.bin/
目录;
具体步骤如下:
-
给终端添加命令查找目录:
因为本地安装的包的可执行文件会被自动链接到node_modules/.bin
目录下,并且Shell变量PWD里保存的是当前所在的目录,所以可以通过$PWD/node_modules/.bin/
来找到本地安装的包的可执行文件的链接,所以要把$PWD/node_modules/.bin/
目录添加为终端的命令查找目录,具体配置为:
在终端的配置文件~/.bash_profile
(如果不存在,则创建该文件)中添加如下代码:export PATH=$PATH:$PWD/node_modules/.bin/
-
开启终端的启动服务:
因为终端只会在新的环境启动时读取终端配置文件(如:.bash_profile),所以启动后Shell变量PATH的值不会自动根据变量PWD更新,并且,如果直接打开终端应用,终端的PWD是用户目录 ~,所以如果以直接打开终端应用方式打开终端,即使再用cd命令转到项目目录,变量PATH也不会正确地指向项目中的node_modules/.bin
目录;
为了能让终端可以在任意目录下启动,需要开启终端的1个或2个服务;开启方法如下:- 打开:系统偏好设置/键盘/快捷键/服务
- 勾选
新建位于文件夹位置的终端标签
或者新建位于文件夹位置的终端标签
;
如下图:
-
在项目目录上(node_modules的父级目录)通过右键的服务菜单打开终端;
如下图:
此方案的特点(不是优点):
- 此方案安装的包是本地包,不是全局包;即可以以全局包的使用方式使用本地包;
此方案的优点:
- 对于任何包都不需要全局安装,只需要安装到项目中即可,但对于可执行文件又具有全局包的方便;
- 有package.json文件,在更换电脑时,方便恢复安装包;
- 不影响npm的更新;
此方案的缺点:
- 不会安装手册页;
方案4:创建npm的链接
此方案的思路:
给本地的安装的包创建一个到全局目录下的符号链接;(详情请参考《[终端常用技巧][]》)
具体步骤如下:
在相应的本地包的目录下执行以下命令:
guobinyongMac:~ guobinyong$ npm link
此方案的特点(不是优点):
- 此方案安装的包是本地包,不是全局包;即可以以全局包的使用方式使用本地包;
- 不影响npm的更新;
此方案的优点:
- 安装包可以安装在任何目录下;
此方案的缺点:
- 会在电脑的全局环境中生成链接,对电脑的全局环境仍有一点点的污染;
- 不会安装手册页;