Reference:(http://firstdoit.com/npm-scripts/)[http://firstdoit.com/npm-scripts/]
1.使用全局安装发生了什么事
一般情况下,我们会使用npm install -g pkg
来安装包,在任何目录下,都可以使用该pkg包提供的命令行工具来执行命令。例如,出名的broserify。在官方的文档中有说明该包的用法,大致分为两步.
第一步是install
安装:
npm install -g browserify
第二步是编译:
$ browserify main.js > bundle.js
那么计算机怎么知道$ browserify
命令执行的是哪个js文件呢?
系统中命令的目标执行文件是按照$PATH
这个系统变量来查找的,那么通过-g参数安装的包都是放到$PATH
路径下的.
那么通过npm install -g
安装的包都放在’/usr/local/lib/node_modules’,在包的package.json中配置了"bin":{"命令名A":"可执行文件的路径",}
,在install命令执行时,在/usr/local/bin
目录下,就会生成一个命令名A
的软连接,该软连接指向的是可执行文件的路径
。
以安装tldr包为例子,(该工具是一个命令行工具,和man <command>
类似,参考https://github.com/tldr-pages/tldr)
1.npm install -g tldr
2.查看其中的package.json
3.在/usr/local/bin
中生成了一个名为「tldr」的软连接,指向的是package.json中配置的目标文件
2 .局部安装发生了什么事
但是,如果我们不想安装成全局的,安装成本地目录下,那么如何在本地目录下通过命令行形式来运行这个npm包提供的命令呢?
还是以tldr为例,只不过这次安装没有-g,只是安装在本地的一个名为nodejs的文件夹下,看看安装的时候,发生了什么事情。
1.在nodejs文件夹下面生成了一个node_modules的文件夹,安装的tldr源码就位于这个文件夹下。
2.但是同时,在node_modules中也有一个.bin的文件夹。里面有一个tldr的软连接,指向的是../tldr/bin/tldr
3.如何命令行运行局部安装的npm包
那么现在的问题是如何在本地通过命令行的方式来运行这个../tldr/bin/tldr
文件
为了说明方法,卸载了全局的tldr,npm uninstall tldr -g
,此时再运行tldr命令,
此时可以使用最傻的办法,当然是这样的,使用node命令(因为是一个js文件)来运行这个命令,(其中的ls是该命令行的参数,请无视。。。),或者直接/node_modules/.bin/tldr ls
也是可以的(因为在tldr文件的顶部有这样一句#!/usr/bin/env node
它告诉shell,可以用node命令来执行我,这和普通给的.sh
文件是类似的。)
,
方法有很多种,
方法一:使用npm run scriptname
,在局部的package.json
中配置了script
字段,那么就可以在该目录下,通过npm run来运行该脚本,nodejs/package.json
中配置如下:
{
"name": "nodeTestDemo",
"version": "1.0.0",
"description": "my own node project",
"main": "index.js",
"scripts": {
"tldr":"./node_modules/.bin/tldr"
},
"keywords": [
"kiwizhang.zd"
],
"author": "kiwi",
"license": "ISC",
"dependencies": {
"iconv-lite": "^0.4.13",
"tldr": "^1.4.0"
},
"devDependencies": {
"mocha": "^2.3.4"
}
}
在nodejs这个目录下运行:
方法二:
通过修改$PATH这个环境变量,让其优先查找当前的./node_modules/.bin
目录,比较野蛮的方法,具体可以参考:
http://stackoverflow.com/questions/9679932/how-to-use-package-installed-locally-in-node-modules下 Linus Gustav Larsson Thiel的回答。同时他也提到了该方法可能安全性方面的问题,具体为何有安全性的问题,我就没有仔细去读了
方法三:
和方法一类似,只不过,此时的script配置略显不同,采用的$(npm bin)
来获取当前目录的node_modules/.bin
"scripts": {
"tldr":"$(npm bin)/tldr"
},