【问题标题】:NPM package 'bin' script for Windows适用于 Windows 的 NPM 包“bin”脚本
【发布时间】:2021-01-23 21:29:44
【问题描述】:

Cucumber.js 提供了一个命令行“二进制”,它是一个简单的 .js 文件,其中包含 shebang 指令:

#!/usr/bin/env node
var Cucumber = require('../lib/cucumber');
// ...

二进制文件在package.json 中使用"bin" 配置键指定:

{ "name" : "cucumber"
, "description" : "The official JavaScript implementation of Cucumber."
// ...
, "bin": { "cucumber.js": "./bin/cucumber.js" }
// ...

这一切都适用于 POSIX 系统。有人在 Windows 上运行 Cucumber.js 时报告了an issue

基本上,.js 文件似乎是通过 Windows 的 JScript 解释器(不是 Node.js)执行的,并且由于 shebang 指令而引发语法错误。

我的问题是:在 UNIX 和 Windows 系统上设置“二进制”脚本的推荐方法是什么?

谢谢。

【问题讨论】:

    标签: windows node.js posix package npm


    【解决方案1】:

    Windows 会忽略 shebang 行 #!/usr/bin/env node 并将根据 .js 文件关联执行它。明确使用节点调用脚本

    node hello.js
    

    ps。 Pedantry:shebangs 不在 POSIX 标准中,但大多数 *nix 系统都支持它们。


    如果您为 Npm 打包项目,请使用 package.json 中的“bin”字段。然后在 Windows 上,Npm 将在您的脚本旁边安装一个 .cmd 包装器,以便用户可以从命令行执行它

    hello
    

    让 npm 正确创建 shim,the script must have the shebang line #!/usr/bin/env node

    【讨论】:

    • 问题是二进制脚本名称以“.js”后缀结尾。 NPM 基于“bin”配置指令创建一个 unix 友好的 cucumber.js 和一个 cucumber.js.cmd windows 友好的二进制文件。由于 Windows 处理文件“扩展”的方式,当键入 node_modules\.bin\cucumber.js 时,它通过 JScript 运行 .js 文件而不是 .cmd 文件。感谢您的迂腐后记;)
    • 我遇到了完全相同的问题。我试图找到一个不需要我告诉 Windows 用户键入不同命令的解决方案。抢占 npm 生成的 .cmd 的 JavaScript 文件在 Windows Script Host 中执行;我希望有一种方法可以利用它来代理节点驱动的 CLI:stackoverflow.com/questions/24113091/…
    • 如何让它由 nodejs 而不是 microsoft jscript 执行?即使将其更改为 node ./index.js 也无法正常工作。更正:重新执行npm link 似乎工作
    • 我和你有同样的问题,错误ENOENT: no such file or directory, chmod 'C:\Users\<user>\AppData\Roaming\npm\node_modules\<module>\node .\index.js'。而在 package.json "bin": { "<module>": "node ./index.js"} 你是怎么解决的?
    • 好的,我添加了#!/usr/bin/env node,即使它适用于 Windows 并且可以正常工作。
    【解决方案2】:

    你的“bin”应该是“cucumber” npm 将创建一个指向“node %SCRIPTNAME%”的“cucumber”或“cucumber.cmd”文件。前者用于 posix 环境,后者用于 Windows 使用...如果您希望“js”成为可执行文件名称的一部分...您应该使用连字符...“cucumber-js”...在您的情况下,拥有 .js 文件将位于 .js.cmd 之前,导致 WScript 解释器将其作为 JScript 文件而不是节点脚本运行。

    我建议以 coffee-script's package.json 为例。

    {
      "name":         "coffee-script",
      "description":  "Unfancy JavaScript",
      "keywords":     ["javascript", "language", "coffeescript", "compiler"],
      "author":       "Jeremy Ashkenas",
      "version":      "1.4.0",
      "licenses":     [{
        "type":       "MIT",
        "url":        "https://raw.github.com/jashkenas/coffee-script/master/LICENSE"
      }],
      "engines":      {
        "node":       ">=0.4.0"
      },
      "directories" : {
        "lib" : "./lib/coffee-script"
      },
      "main" : "./lib/coffee-script/coffee-script",
      "bin":          {
        "coffee":     "./bin/coffee",
        "cake":       "./bin/cake"
      },
      "scripts": {
        "test": "node ./bin/cake test"
      },
      "homepage":     "http://coffeescript.org",
      "bugs":         "https://github.com/jashkenas/coffee-script/issues",
      "repository":   {
        "type": "git",
        "url": "git://github.com/jashkenas/coffee-script.git"
      },
      "devDependencies": {
        "uglify-js":  ">=1.0.0",
        "jison":      ">=0.2.0"
      }
    }

    【讨论】:

      【解决方案3】:

      我设法找到了解决类似问题的方法。

      我最初的计划是只为 API 和 CLI 提供一个大的 .js 文件(原因是因为当时我不知道如何在两个文件之间共享变量)。当一切都构建好后,我尝试将#!/usr/bin/env node shebang 添加到我的文件中。但是,这并没有阻止 Windows 脚本宿主给出错误。

      我最终提出了一个“变量桥”的想法,它允许使用getVarsetVar 读取和设置变量。这让我不得不从 API 代码中提取 CLI 代码并将一些导入添加到变量桥中。

      在 CLI 文件中,我添加了 shebang,并将我的项目的 package.json 修改为:

      {
          ...
          "main": "./bin/api.js",
          "bin": {
              "validator": "./bin/cli.js"
          }
          ...
      }
      

      如果 Windows Script Host 仍然出现错误,我认为以下几点可能会有所帮助(我应用了所有这些,所以我不确定哪一个有帮助):

      • 只使用 LF 行尾似乎有帮助。

      • 似乎./bin 是编译文件的首选目录。我确实尝试过./dist,但它对我不起作用。

      • shebang 后面可能需要一个空行:

        // cli.js
        
        #!/usr/bin/env node
        
        // code...
        
      • package.json 中为mainbin 使用相同的名称似乎对我来说是个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-04
        • 2022-08-14
        • 2021-10-27
        • 2014-08-11
        • 1970-01-01
        • 2021-06-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多