使用.bash_profile和“postinstall”脚本避免NPM全局安装

NPM的理念,无论好坏,都是为了在本地安装一个项目的所有必要的依赖项,在./node_modules和package.json中反映所有必要的代码。

我有一个图书馆,这通常会受益于全球安装和本地安装,类似于Gulp,Mocha等。

以上最棘手的问题之一是,全球和本地版本可能会有所不同,导致给定项目的兼容性问题。

我想我们可以通过在.bash_profile创build一个别名来避免这个问题,例如:

 # bash psuedocode * alias gulp='using current working directory, find the locally installed gulp and run that' 

我的图书馆不是咕嘟咕嘟,但你明白了。 我知道很多开发者不喜欢第三方写给他们的bash_profiles的想法,但是我认为这有点肛门保留,考虑到做这样的事情没有外部效应(TMK)。

所以我有三个问题:

(1)这是个好主意吗?

(2)有没有什么项目可以做类似的事情?

(3)我对bash脚本不是很了解,你如何编写一个bash脚本来recursion查找node_modules / .bin / gulp,如果你的开发者从项目内的目录运行gulp命令,而不是在根目录?

我的想法是,作为后安装脚本

 npm install --save-dev gulp 

我们将运行一个脚本

  1. 将上面的行*添加到.bash_profile
  2. 在这一行中,我们将指向存储在/Users/you/.gulp下的脚本,该脚本将负责定位本地安装的吞咽。

这样,我们可以节省模块的全局安装需求,只用于命令行的方便,同时也减轻了不同软件包版本的问题。

我会一一浏览你的三个问题:

(1)这是个好主意吗?

没有。自动更改用户的私人文件从来不是一个好主意,如果你这样做的话,我会看到几个可怕的错误 – 从纯粹烦恼的用户不得不清理你的程序,破坏用户的系统configuration,到严重的安全问题。

(2)有没有什么项目可以做类似的事情?

我希望不是。 我永远不会运行任何与我的.bash_profile – 即使我没有。 我有.profile.bashrc 。 这对你来说又是一个问题 – 你确定你甚至知道要编辑什么吗? 如果我使用有时使用的dash ,或者zsh或其他shell,该怎么办?

(3)我对bash脚本不是很了解,你如何编写一个bash脚本来recursion查找node_modules / .bin / gulp,如果你的开发者从项目内的目录运行gulp命令,而不是在根目录?

如果您对bash脚本编程不是很好,那么您绝对不应该自动编辑用户的私有文件。

可以做的是在一个单独的文件中提供一个特定的别名或bash函数,以方便用户,并解释用户如何在你的.bashrc文件中find他们想要的文件。

但是从不为他们做出这个决定。 如果出现任何问题,甚至可能对您造成法律后果。

function的例子

回答您在评论中发布的问题,我将在Bash中添加几个关于函数如何工作的文字。

在我的GitHub脚本收集中,我有几个函数说明如何安装以及如何使用它们 。 他们的源代码在这里可用。

该集合中的示例函数是可以的 – 这是它的源代码:

 ok() { # prints OK or ERROR and exit status of previous command s=$? if [[ $s = 0 ]]; then echo OK else echo ERROR: $s fi } 

您可以从下载(与一些其他相关的function):

如果将其保存为~/ok-functions则可以运行:

 source ~/ok-functions 

让它们在那个会话中可用,或者你可以把这行放在.profile.bashrc以便在每次login后都可用。 你可以像使用正常的命令或程序一样使用它:

 ls /bin; ok ls /binn; ok 

阻止全局安装的工作示例

我写了一个Bash函数来完成你正在做的事情 – 它停止了某个模块的全局安装 – 在这个例子中叫做modname 。 将它保存到某个文件中 – 例如~/no-global-restricted-module – 当然你可以在n改变restricted-module名称,在w改变警告信息以满足你的需求:

 npm() { n=restricted-module w="Please don't install $n globally - see: http://example.com/" i=0 g=0 m=0 for a in "$@"; do case $a in i|install) i=1;; -g|--global) g=1;; $n) m=1;; esac done if (( $i == 1 && $g == 1 && $m == 1 )); then echo $w >&2 return 1 else `which npm` "$@" fi } 

然后将这一行添加到~/.profile~/.bashrc

 source ~/no-global-restricted-module 

现在当你再次login时,或者当你打开一个新的terminal窗口,你可以尝试在你的命令行中运行这个:

 npm install --global restricted-module 

您应该看到一个警告,不会开始安装。 如果您input其他模块名称或省略了--global开关,那么安装应该照常进行。 这也适用于i的快捷键,而不是install-g而不是--global

这几乎是你想要做的。 您可以在文档中包含该function,并说明如何使用它。 我现在根据MIT许可证的条款发布它,所以你可以自由使用它。 我在GitHub上发布了一些关于如何使用它的configuration和信息的选项,请参阅:

也可以看看

另请参阅此答案 ,以更好地解释如何在terminal中播放各种声音的示例中编写,安装和使用Bash函数。