【问题标题】:Pass command line -- argument to child script in Yarn将命令行 -- 参数传递给 Yarn 中的子脚本
【发布时间】:2018-11-22 22:00:35
【问题描述】:

我有一个类似于此的 package.json:

"scripts": {
    "dev": "cross-env BABEL_ENV=client webpack --config webpack/client.development.js && yarn dev:stub-server | cross-env BABEL_ENV=server babel-node src/server/server.js",
    "dev:stub-server": "./node_modules/.bin/robohydra ./stubs/robohydra-config.json -p 3100"
}

我在代码中添加了一些逻辑来更改 dev:stub-server 的配置方式,具体取决于命令行参数。因此,每当我运行以下命令时,我都会得到我所期望的:

yarn dev:stub-server --results=4
$ ./node_modules/.bin/robohydra ./stubs/robohydra-config.json -p 3100 -- --results=4

如您所见,选项被转发到底层脚本,一切都按预期工作。

我的问题是我无法将--resultsyarn dev 命令传播到正确位置的dev:stub-server。父脚本运行dev:stub-server,但参数在最后被转发到底层脚本,如下所示:

yarn dev --results=2
$ cross-env BABEL_ENV=client webpack --config webpack/client.development.js && yarn dev:stub-server | cross-env BABEL_ENV=server babel-node src/server/server.js --results=2

有没有办法使上述工作改为如下?

yarn dev --results=2
$ cross-env BABEL_ENV=client webpack --config webpack/client.development.js && yarn dev:stub-server --results=2 | cross-env BABEL_ENV=server babel-node src/server/server.js

提前致谢!

【问题讨论】:

    标签: node.js npm package.json yarnpkg npm-scripts


    【解决方案1】:

    Yarn's run 仅支持将您的 args 附加到命令链的末尾,并且至少截至日期 2018-06-14,没有办法覆盖它。

    当我过去需要这个时,我已经编写了自己的 dev.js 脚本,由我的 package.json 调用,并从环境变量中提取 args。

    【讨论】:

      【解决方案2】:

      在我使用的 mac 上:

      "scripts": {
        "benchmark": "sh -c 'ng run ${0}:benchmark'",
      }
      

      然后我调用yarn benchmark editor,其中editor 是我的参数。

      【讨论】:

      • 这在 Windows 上当然会失败,除非你可以告诉使用你的包的每个人他们需要安装 bash(通过 cygwin 或 Windows 的 git)。我认为这对于开源来说是不合理的,但我在我的闭源项目中到处使用它。
      • 嗨,这太棒了,但是我可以将参数传递到执行脚本中的某个地方吗?我需要类似yarn semistandard --fix $(git diff --name-only HEAD HEAD~${0})
      • 天哪,这救了我 - 非常感谢!你知道为什么它从 0 而不是 1 开始吗?
      【解决方案3】:

      作为替代方案,您可以在脚本中使用*.env 文件和cat 变量。

      "run":"docker build -t --build-arg VAR=`cat vars.env` -f Dockerfile .
      

      例如

      【讨论】:

        【解决方案4】:

        像这样做。因为纱线本质上会传递参数。

        "scripts": {
          "runSomeShellScriptAlpha": "path/to/script_name.sh  $1 $2 $3", // redundant $x
          "runSomeShellScriptBeta": "path/to/script_name.sh",            // better 
        }
        
        yarn runSomeShellScriptBeta p1 p2 p3
        

        Alpha 版仅适用于Mac/Linux,不适用于Win10。这很糟糕。

        测试版同时适用于Mac/LinuxWin10

        【讨论】:

        • 这对我不起作用——它不能取代{script_name}——我可能遗漏了什么吗?
        • {script_name} 表示自定义文件名。它不是变量,不会被shell 替换。引起误解的括号很抱歉
        【解决方案5】:

        我在这里发布了一些东西(2 行代码)。 https://stackoverflow.com/a/65265945/12463120

        需要注意的是,Webpack 不会转发 CLI。所以,你必须先保存它们。

        // webpack.config.js 
        process.env.MY_APPLICATION_NAME_ARGS = JSON.stringify(process.argv)
        
        // your.script.js
        const myArgs = JSON.parse(env.MY_APPLICATION_NAME_ARGS )
        

        【讨论】:

          【解决方案6】:

          实现此目的的一种简单方法是使用parameter expansion with $* 编写an inline Bash function

          "scripts": {
              "dev": "wrap () { node index.js \"$*\" | cat; }; wrap"
          }
          

          使用yarn dev foo bar 调用上述代码将运行node index.js foo bar,然后将结果通过管道传输到cat 作为演示。
          您可以将命令添加到开头和结尾,只需记住此处需要 semis。

          对于更多涉及的内容,您可能需要一个独立的脚本。

          【讨论】:

          • 这真是太棒了。
          • @Etheryte 我在这里遗漏了一些非常基本的东西。在 Windows 上,我在 git bash 中运行类似的内联 bash 函数,但得到了wrap is not recognized as an internal or external command...。知道是什么原因造成的吗?
          • 适用于遇到与 YARN 用户相同问题的任何人。 Yarn 默认使用bin\sh,这个特殊的内联 Bash 函数不能在其中运行。你需要通过执行这个yarn config set script-shell bin\bash来设置Yarn使用bin\bash
          【解决方案7】:

          就目前而言,使用yarn 1.22.4 您可以使用yarn exec tsc -- --help。附加 -- 就可以了

          【讨论】:

            【解决方案8】:

            使用 npm 功能将命名的自定义参数传递给命令行,作为您的 yarn 命令的代理:

             "scripts": {
                  "yarn-cmd": "npm run npm-cmd --foo=bar",
                  "npm-cmd": "echo \"foo value is $npm_config_foo\""
                }
            

            运行yarn yarn-cmd

            阅读更多:https://docs.npmjs.com/cli/v7/using-npm/config

            【讨论】:

              【解决方案9】:

              您可以在 preScript、Script 和 postScript 中剖析您的脚本。

              我有一个 git typescript 库项目示例:

              "predeploy": "yarn build",
              "dodeploy": "yarn config set version-git-message ",
              "postdodeploy": "yarn version --minor && yarn config set version-git-message 'v%s'"
              

              然后运行

              yarn dodeploy "my custom message"       
              

              【讨论】:

              • 您能详细说明一下吗? v%s 是什么?为什么set 被调用了两次?命令运行时会发生什么?
              • Frank,这是因为 yarn 或 npm version 命令有自己的提交信息,由 version-git-message git 参数指定,默认值为 'v%s'。这个参数'v%s',是版本号。因此,当我 dodeploy “我的自定义消息”时,我将版本-git-message 参数设置为“v%s”。到“我的自定义消息”。在此之前,会执行一个 yarn build 命令。 dodeploy 脚本完成后,执行 postdeploy 命令。这里我只恢复默认的版本-git-消息参数。
              猜你喜欢
              • 2014-03-08
              • 2013-10-22
              • 2016-12-19
              • 1970-01-01
              • 2013-10-11
              • 1970-01-01
              • 2020-05-09
              相关资源
              最近更新 更多