【问题标题】:How can I make npm projects with Bash shell commands work on Windows?如何使用 Bash shell 命令使 npm 项目在 Windows 上运行?
【发布时间】:2019-08-13 11:42:35
【问题描述】:

我最近接手的一个项目中有一些 NPM 脚本,如下所示:

{
    "package": "yarn package-common && mv './dist/APP® TV.wgt' ''./package/$(yarn -s filename)''",
    "package-common": "tizen package -t wgt -s APP -- ./dist && rimraf package && mkdir package",
    "filename": "cross-env-shell echo APP_${npm_package_version}.wgt",
}

这个项目是由某人在 MAC 上编写的。如何将以下部分转换为功能正常的 Powershell / cmd 命令?我还没有在任何地方找到任何关于此的内容。它运行命令并将回显的值附加到调用它的字符串中。

''./package/$(yarn -s filename)''

或者更好的是,除了this 包之外还有什么方法可以跨平台吗?

目前运行 yarn 包时在 powershell 中输出的消息是:

'' was unexpected at this time.

【问题讨论】:

  • 顺便说一句:错误消息来自cmd.exe,npm 在 Windows 上默认使用。
  • 如果需要跨平台,我建议在 node.js 脚本中重写它,并使用@987654322 shell-out 必要的命令@(或 exec,如果你想要异步)。然后,您可以通过 npm 脚本调用 node.js 脚本,即"package": "node somescript.js"
  • 或评估(即node -e ...)从您的 npm 脚本内联的 node.js 脚本。例如。 "package": "yarn package-common && node -e \"var sh = require('child_process').execSync; var fn = sh('yarn -s filename', {encoding: 'utf8'}); sh('mv ./dist/APP®TV.wgt ./package/' + fn);\"", 这将跨平台运行,但是脚本中最有问题的部分是路径./dist/APP® TV.wgt 中注册符号加上空格字符的组合。这是 cmd.exe 的编码噩梦。我建议你将它(如果可以的话)更改为例如./dist/APP®TV.wgt 按照上述 npm 脚本。
  • 对于使用 npm 默认 cmd.exe 在仅限 Windows 的环境中运行,您可能需要考虑将您的 package 脚本更改为:"package": "yarn package-common && FOR /F %f IN ('yarn -s filename') DO mv ./dist/\"APP®TV.wgt\" ./package/%~f", - 这也需要将./dist/APP® TV.wgt 路径更改为./dist/APP®TV.wgt,即省略注册符号加空格字符的组合来否定编码噩梦。

标签: shell powershell npm cmd command-line


【解决方案1】:

您对于跨平台没有平台特定脚本的基本选择是:

  • 在 Windows 上也使用 Bash

    • 通过WSL从 Bash 运行您的 npm 脚本并使用通常包含在 package.json 文件中的现有 Bash 命令,例如您的情况。

    • 或者,安装 Git for Windows 后,将 npm 配置为使用 bash.exe 作为调用命令的 shell - 请参阅 this answer [npm v5.1+]。

  • 在所有平台上安装PowerShell (Core)(包括 Windows),并将命令定义为 PowerShell 命令(见下文)[npm v5.1+]。

注意 npm 版本要求(5.1 或更高版本),因为在早期版本中不提供使用特定 shell (script-shell) 的配置选项。运行npm -v 获取已安装的版本,如果可能,运行
npm install -g npm 进行更新。


在所有平台上使用带有 PowerShell(核心)的 npm [npm v5.1+]:

  • Install PowerShell 核心。

  • 然后将 npm 配置为使用 PowerShell (Core) 作为 shell(需要 npm 5.1 或更高版本):

    • 对于所有您的项目(当前用户),或全局(所有用户):

      npm config set script-shell pwsh [--global]
      
    • 仅针对给定项目(来自该项目的根目录):

      npm config set script-shell pwsh --userconfig ./.npmrc
      
  • 最后,在您项目的 package.jsonscripts 键中,将命令定义为 PowerShell 命令。

在手头的情况下:

例如,翻译这个 Bash 命令:

yarn package-common && mv './dist/APP® TV.wgt' "./package/$(yarn -s filename)"

注意:我已将'' 替换为",因为后者更有意义;正如最初所写的那样,'' 被 Bash 有效地丢弃,如果命令替换 $(yarn -s filename) 包含空格,则它可能会破坏命令。

到这个 PowerShell 命令 (v7+):

yarn package-common && mi './dist/APP® TV.wgt' "./package/$(yarn -s filename)"

注意:

  • mi 是 PowerShell 的 Move-Item cmdlet 的内置别名。

  • 虽然也可以从 PowerShell 调用脚本,但这不是必需的 - 从 cmd.exe 或批处理文件调用也可以。

  • 要开始使用 PowerShell(核心),请参阅 Learning PowerShell;此外,http://hyperpolyglot.org/shell 将 Bash 等类似 POSIX 的 shell 的语法与 cmd.exe 和 PowerShell 的语法以简洁的表格形式并置。

【讨论】:

    【解决方案2】:

    我将无耻地宣传我对这个问题的解决方案。我面临同样的问题,并决定编写一个小工具来一劳永逸地解决这个问题。结果是一个小型 Bash 解释器,它能够在所有可以运行 NodeJS 的平台上工作,包括 Windows。作为一个不错的奖励,它还支持并行运行任务。

    简而言之,您可以将npm run x 替换为bake x,它会起作用。该命令后指定的所有脚本都将并行运行,如果您将 @samvv/bake 作为依赖项安装,您也可以在 npm 脚本中使用它,如下所示:

    {
      "scripts": {
         "watch:compile-tests": "tsc -w",
         "watch:tests": "ava --watch",
         "test": "ava",
         "lint": "tsc --noEmit",
         "prepare": "npm run lint && webpack --mode production",
         "serve": "webpack serve --mode development",
         "lint-while-testing": "bake lint test"
      }
    }
    

    您可以找到源代码here,并且可以使用npm install -g @samvv/bake 安装该软件包。请参阅this Medium post,了解有关其工作原理和使用方法的更多信息。

    我真的希望这对某人有用!

    【讨论】:

      猜你喜欢
      • 2019-10-04
      • 2020-02-12
      • 2015-09-03
      • 2016-01-14
      • 2013-01-31
      • 2018-04-07
      • 1970-01-01
      • 2020-08-16
      • 1970-01-01
      相关资源
      最近更新 更多