【问题标题】:How to detect when `prepublish` script is executed as a result of running `npm install`如何检测由于运行`npm install`而执行`prepublish`脚本的时间
【发布时间】:2016-04-08 09:59:12
【问题描述】:

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

prepublish:在包发布之前运行。 (也可以在本地 npm install 上运行,不带任何参数。)

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

【问题讨论】:

    标签: node.js npm


    【解决方案1】:

    我想出的唯一方法是使用 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 变量之类的操作不起作用。

    【讨论】:

    • github.com/npm/npm/issues/3059这似乎是一个非常有争议的决定。我一直在使用的一种解决方法是 npm install --ignore-scripts(如上面脚本中所建议的那样)。
    • 你把这段代码放在哪里?您的预发布脚本是用js 编写并由node 运行的吗?你如何从你的package.json 文件中调用它?
    【解决方案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 目标将在用户键入npm run publish 时被调用。

    还有一种方法是使用in-publish 包(在this thread 中再次提到)。将它放在您的开发依赖项中,然后在您的 package.json 中具有类似的内容:

    "prepublish": "(in-publish && npm run clean && flow check && npm run test && npm run build) || not-in-publish" 
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2017-01-13
        • 2014-12-14
        • 1970-01-01
        • 1970-01-01
        • 2017-11-05
        • 2017-03-10
        • 2013-10-25
        • 1970-01-01
        • 2022-11-20
        相关资源
        最近更新 更多