如何检测由于运行`npm install`而执行`prepublish`脚本的时间

时间:2016-01-04 18:03:56

标签: node.js npm

https://docs.npmjs.com/misc/scripts

  

prepublish:在发布包之前运行。 (也可以在没有任何参数的本地npm安装上运行。)

我希望我的脚本仅在用户执行npm publish的情况下执行。但是,如果用户运行“npm install”,NPM将执行“prepublish”脚本。

3 个答案:

答案 0 :(得分:4)

我唯一想到的方法是使用NPM内部ENV变量:

// NPM will run prepublish script after `npm install` (https://docs.npmjs.com/misc/scripts)
// This ensures that when script is executed using `npm *` it is run only when the command is `npm publish`.
if (process.env.npm_config_argv) {
    let npmConfigArgv;

    npmConfigArgv = JSON.parse(process.env.npm_config_argv);

    if (npmConfigArgv.original[0] !== 'publish') {
        console.log('`bundle-dependencies prepublish` will not execute. It appears that `prepublish` script has been run by `npm install`.');

        return;
    }
}

NPM似乎将原始命令存储在process.env.npm_config_argv变量中。

如果您想知道,每个NPM脚本都在不同的进程中运行。因此,在preinstall脚本中设置自定义ENV变量之类的操作无效。

答案 1 :(得分:2)

另一个对我有用的解决方案(同样来自this thread)正在使用prepublish.sh脚本,如下所示:

get_json_val() {
    python -c "import json,sys;sys.stdout.write(json.dumps(json.load(sys.stdin)$1))";
}
get_npm_command() {
    local temp=$(echo $npm_config_argv | get_json_val "['original'][0]")
    echo "$temp" | tr -dc "[:alnum:]"
}
if [ $(get_npm_command) != "publish" ]; then
    echo "Skipping prepublish script"
    exit 0
fi
# else
echo "prepublish called"
# prepublish logic follows:
# ...

因此,如果您的package.json文件是:

{
  "name": "foo",
  "version": "0.0.1",
  "description": "",
  "main": "lib/foo.js",
  "scripts": {
       "prepublish": "./prepublish.sh"
  },
  "dependencies": {
    "lodash": "^4.10.0"
  }
}

...然后运行npm install安装依赖项,当用户键入prepublish时,{em}仅{<1>}目标将调用

另一种方法是使用npm run publish包(在this thread中再次提及)。将它放在您的开发依赖项中,然后在in-publish中使用类似的内容:

package.json

答案 2 :(得分:1)

npm@4.0.0 开始,prepublish script is now deprecated。要在npm publishnpm install不带参数(prepublish的行为)的情况下运行脚本,您应该使用 prepare

要仅在npm publish上运行脚本,您应该使用 prepublishOnly