使用.bash_profile和“postinstall”避免NPM全局安装脚本 [英] Avoiding NPM global install using .bash_profile and "postinstall" script

查看:109
本文介绍了使用.bash_profile和“postinstall”避免NPM全局安装脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

NPM理念无论好坏,都需要在本地安装一个项目所需的所有依赖项,位于 ./ node_modules 中,package.json反映所有必需的代价。



我有一个库,它通常受益​​于全局安装和本地安装,类似于Gulp,Mocha等。
$ b

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



在我看来,我们可以通过在 .bash_profile 中创建一个别名来避免这个问题,如下所示:

 #bash psuedocode 
* alias gulp ='使用当前工作目录,找到本地安装的gulp并运行'

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



所以我有三个问题:
$ b


(1)这是个好主意吗?



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

<3>我对bash脚本不太了解,你如何编写一个bash脚本
,如果你的开发
从项目
中的某个目录运行gulp命令,而不是在
中,则可递归查找node_modules / .bin / gulp根??/ b>

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

  npm install --save-dev gulp 

我们会运行一个脚本


  1. 将上述行*添加到.bash_profile

  2. 中,我们会指向存储的脚本在/Users/you/.gulp下面,它将负责查找本地安装的gulp。

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

解决方案

我会一一浏览您的3个问题:


(1)这是个好主意吗?


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


(2)是否有任何项目可以做类似的事情?怎么样?

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


(3)对于bash脚本,我不是一个好主意,你如何编写一个bash脚本来递归查找node_modules / .bin / gulp gulp命令从项目内的目录,但不在根目录中?


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



可以做的是提供某种别名或bash功能在一个单独的文件中为了用户的方便,并解释用户如何在 .bashrc 中输入文件>。



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



函数示例



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



我在GitHub上收集的脚本我在如何安装如何使用它们。他们的源代码此处



该集合中的示例函数是 ok - 这是它的源代码:

  ok(){
#打印OK或ERROR并退出前一个命令的状态
s = $?
if [[$ s = 0]];然后
echo OK
else
echo ERROR:$ s
fi
}

您可以从以下网址下载它(以及其他相关功能):



如果将它保存为〜/ ok-functions ,则可以运行:

  source〜/ ok-functions 

使它们在该会话中可用,或者您可以将该行放入 .profile .bashrc 在每次登录后都可用。你可以使用它,就像它是一个普通的命令或程序一样:

  ls / bin;好的
ls / binn; OK



阻止全局安装的工作示例

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

  npm(){
n = restricted-module
w =请勿全局安装$ n - 请参阅:http://example.com/$ b对于$ @中的$ bi = 0
g = 0
m = 0
;
case $ a
i | install)
i = 1 ;;
-g | --global)
g = 1 ;;
$ n)
m = 1 ;; ($ i == 1&& $ g == 1&& $ m == 1));
esac
完成
然后
echo $ w>& 2
return 1
else
`which npm`$ @
fi
}

然后将此行添加到〜/ .profile 〜/ .bashrc

 源〜/无全局限制-module 

现在,当您再次登录或打开新的终端窗口时,您可以尝试在你的命令行中运行它:

  npm install --global restricted-module 

您应该看到警告,并且不会开始安装。如果您输入其他模块名称或省略 - global 开关,则安装过程应照常进行。这也适用于 i 而不是安装 -g 而不是 - 全局



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



另见



另见这个答案更好地解释了在终端播放各种声音的例子中编写,安装和使用Bash函数。


NPM philosophy, for better or worse, is to have all necessary dependencies for a project to be locally installed, in ./node_modules, and for package.json to reflect all necessary deps.

I have a library, that would typically benefit from both global installation and local installation, similar to Gulp, Mocha, etc.

One of the most insiduous problems with the above, is that the global and local versions might differ, causing compatibility issues for a given project.

It occurred to me that we could avoid this problem, by creating an alias in .bash_profile, something like this:

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

My library is not Gulp, but you get the idea. I know a lot of devs don't like the idea of 3rd parties writing to their bash_profiles, but I think that is a bit anal-retentive, considering doing something like this has zero outside effects (TMK).

So I have three questions:

(1) Is this a good idea?

(2) Are there any projects that do something similar and how?

(3) I an not great with bash scripting, how do you write a bash script that can recursively look for node_modules/.bin/gulp if you the dev runs the gulp command from a directory that is within the project but not in the root?

My thinking was that as a postinstall script to

npm install --save-dev gulp

we would run a script that

  1. added the above line* to the .bash_profile
  2. in that line, we would point to a script stored under /Users/you/.gulp that would be responsible for locating the locally installed gulp.

This way we save the need for global installations of modules, when they are only used for command line convenience, as well as alleviating the problem of differing package versions.

解决方案

I'll go through your 3 questions one by one:

(1) Is this a good idea?

No. Changing user's private files automatically is never a good idea and I see several things that can go horribly wrong if you do that - from a pure annoyance of users having to clean after your programs, to breaking user's system config, to serious security problems.

(2) Are there any projects that do something similar and how?

I hope not. I would never run any program that messes with my .bash_profile - even though I don't have it. I have .profile and .bashrc. And that's another problem for you - are you sure you even know what to edit? What if I use dash which I use sometimes, or zsh or some other shell?

(3) I an not great with bash scripting, how do you write a bash script that can recursively look for node_modules/.bin/gulp if you the dev runs the gulp command from a directory that is within the project but not in the root?

If you are not great with bash scripting then your definitely should not edit user's private files automatically.

What you can do is to provide a certain alias or bash function in a separate file for user's convenience and explain how users can source your file inside of their .bashrc if they want to.

But never make that decision for them. If anything goes wrong this can even have legal consequences for you.

Examples of functions

Answering your questions posted in the comments, I'll add few words on how functions work in Bash.

In my collection of script on GitHub I have few functions with instructions on how to install them and how to use them. Their source code is available here.

An example function in that collection is ok - this is its source code:

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

You can download it (with some other related functions) from:

If you save it as ~/ok-functions then you can either run:

source ~/ok-functions

to have them available in that session, or you can put that line in .profile or .bashrc to have it available after every login. You can use it as if it was a normal command or program like this:

ls /bin; ok
ls /binn; ok

Working example of preventing global install

I wrote a Bash function that does what you are trying to do - it stops global installation of a certain module - called modname in this example. Save it to some file - e.g. to ~/no-global-restricted-module - of course you can change the restricted-module name in n and the warning message in w to suit your needs:

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
}

And then add this line to your ~/.profile or ~/.bashrc:

source ~/no-global-restricted-module

Now when you log in again, or when you open a new terminal window, you can try running this in your command line:

npm install --global restricted-module

You should see a warning and no installation will be started. If you enter some other module name or you omit the --global switch then the installation should proceed as usual. This also works with the shortcuts of i instead of install and -g instead of --global.

This is pretty much what you are trying to do. You can include that function in your documentation with instructions on how to use it. I am hereby releasing it under the terms of the MIT license so you can use it freely. I published it on GitHub with some more options for configuration and information on how to use it, see:

See also

See also this answer for a much better explanation of writing, installing and using Bash functions on the example of playing various sounds in the terminal.

这篇关于使用.bash_profile和“postinstall”避免NPM全局安装脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆