通过 npm 脚本从 Powershell 使用 --collectCoverageFrom 运行 Jest 测试时,转义引号和斜杠的正确方法是啥?

Posted

技术标签:

【中文标题】通过 npm 脚本从 Powershell 使用 --collectCoverageFrom 运行 Jest 测试时,转义引号和斜杠的正确方法是啥?【英文标题】:What is the proper way to escape quotes and slashes when running a Jest test with --collectCoverageFrom from Powershell via npm scripts?通过 npm 脚本从 Powershell 使用 --collectCoverageFrom 运行 Jest 测试时,转义引号和斜杠的正确方法是什么? 【发布时间】:2022-01-04 05:15:12 【问题描述】:

我是一名 React 开发人员,习惯于在 Linux 中从 Bash 运行如下示例的命令,但现在我必须通过 Powershell 使其在 Windows 环境中运行:

npm test ExampleComponent --collectCoverageFrom='["**/ExampleComponent.tsx"]' --watch

npm 测试脚本中只有“jest”,但我需要通过脚本使用它,以便我在项目中使用 jest 的版本,而不是全局。

我在尝试填补特定文件 (ExampleComponent.tsx) 中代码覆盖率的空白时使用它,因此我希望 Jest 在我保存对测试文件的更改时重新评估该文件的覆盖率 (@987654323 @ 在这种情况下)。

这是我在 Powershell 中运行的(在 "--" 中添加了引号,因为 Powershell 不像 bash 那样对待 --,并且在 Windows 中从正斜杠切换到反斜杠):

npm test "--" ExampleComponent --collectCoverageFrom='["**\ExampleComponent.tsx"]' --watch

这是根据 npm 的输出调用 jest 的方式:

jest "ExampleComponent" "--collectCoverageFrom=[**\ExampleComponent.tsx]" "--watch"

在 Powershell(版本 7.2,如果这很重要)中,上面的命令不会将覆盖检查限制到指定的文件。它只测试指定的文件,但collectCoverageFrom 选项被忽略,大概是因为 jest 接收的模式被 Powershell 破坏了。

如何从 Powershell 命令行中转义引号和斜杠以复制顶部的 bash 调用?根据有关在 Powershell 中转义的答案,我尝试了多种反斜杠和多个引号的组合,但到目前为止它们都没有奏效。

【问题讨论】:

【参考方案1】:

Powershell 7.2.1 版更新:

三重反斜杠似乎不再需要了;此答案先前版本中的语法不再对我有用。但以下工作:

npm t "--" ExampleComponent --collectCoverageFrom="'[\""**/ExampleComponent.tsx\""]'"

Jest 使用此语法回显与之前相同的内容,如下所述。

以前的版本:


我找到了一个可行的版本:

npm t "--" ExampleComponent --collectCoverageFrom="'[\\\""**/ExampleComponent.tsx\\\""]'"

该命令似乎按预期运行,仅计算指定文件的覆盖率。

Jest 将命令回显为:

jest "ExampleComponent" "--collectCoverageFrom='[\"**/ExampleComponent.tsx\"]'"

处理后的版本在双引号之前有反斜杠,因为整个参数已经包含在双引号中。我还必须将反斜杠改回正斜杠。

感谢@mklement0 在问题的 cmets 中提供的意见。

【讨论】:

【参考方案2】:

Your solution是有效的,但是让我补充一下重要的背景信息:

核心问题是一个可悲的现实,即至少在 PowerShell 7.2 之前有一个 额外的手动\ -转义嵌入式 "传递给外部程序的参数中需要字符。这可能在未来的版本中得到修复,可能需要选择加入。详情请见this answer。

在您的特殊情况中,由于必须执行此转义两次,问题显然更加复杂,因为涉及两个调用:首先,到npm,然后中继它收到的一些参数到jest

最终,您希望jest 在解析自己的命令行(在 Windows 上)后看到的逐字逐句是以下字符串:

--collectCoverageFrom='["**/ExampleComponent.tsx"]'

顺便说一句:您的bash 命令确实没有实现,因为' 具有句法 功能(就像它们一样在 PowerShell 中)并且在传递结果字符串之前被bash删除

如果图片中没有 PowerShell 错误,您将使用以下内容:

npm t '--' ExampleComponent --collectCoverageFrom='''["**/ExampleComponent.tsx"]'''

注意嵌入在整体'...'verbatim string 中的'',它们被转义 ' 字符。 逐字逐句包含在字符串中。

或者,您可以使用"..." 进行外部引用,这需要您转义嵌入的" 字符。作为`"(或""[1]):

npm t '--' ExampleComponent --collectCoverageFrom="'[`"**/ExampleComponent.tsx`"]'"

但是请注意,这种双引号字符串是expandable strings,即受字符串插值的影响。通常最好将逐字字符串 ('...') 用于 不需要 需要插值的字符串,以便概念清晰并防止可能不需要的插值(这里不是问题,因为该字符串不包含任何含义 -将逐字逐句 $`characters)。

没有关于嵌入的" 字符的错误,没有中继 参数的问题 - 无论执行多少次。


事实上,如果您在 PowerShell 7.2 上,您可以完成这项工作,但只有明确启用 PSNativeCommandArgumentPassing experimental feature

Enable-ExperimentalFeature PSNativeCommandArgumentPassing 然后启动一个新会话以使更改生效。 在新会话中,运行 $PSNativeCommandArgumentPassing = 'Standard' 以便也将修复应用到 批处理文件*.cmd*.bat),这是必要的,因为实现了 npm CLI作为一个。 不幸地需要一个每个会话的额外步骤是一个非常不幸的设计决定的结果,默认(值'Windows'豁免批处理文件和来自修复的 WSH 脚本文件(JScript、VBScript),而不是应用目标脚本引擎适当的修复自动 - 请参阅GitHub issue #15143 中的对话

稍后运行Disable-ExperimentalFeature PSNativeCommandArgumentPassing 以再次禁用它。


存在错误:

嵌入 " 字符 在您的字符串中需要手动 \-转义 ,由于该错误 - 无论您使用 '...' 还是 "..." 字符串:

如果只涉及一个调用,这意味着:

# Note the \-escaped "
npm t '--' ExampleComponent --collectCoverageFrom='''[\"**/ExampleComponent.tsx\"]'''

这将使npm 看到所需的逐字字符串。

因为 npm 然后 中继 有问题的参数jest必须应用 额外的轮转义
# Note the \-escaped ", preceded by an \-escaped \
npm t '--' ExampleComponent --collectCoverageFrom='''[\\\"**/ExampleComponent.tsx\\\"]'''

即:

npm 的调用有效地将\" 转换为" 因为参数随后中继,它必须再次手动\-转义,以便" 字符。也保留在对 jest 的调用中。 通过在 \\ 前面添加 - 即 转义 \ 到 - \" (\\\"),npm 最终会看到 逐字 \" ,当通过 PowerShell 中继时,jest 会根据需要仅看到 "

[1] 虽然"""..." 内部工作正常,但它在那里工作。相比之下,`" 使用 PowerShell 的 general 转义字符,即反引号 (`) - 并且无论上下文如何,只需要记住那个 one 字符会减少内存给用户带来负担。

【讨论】:

以上是关于通过 npm 脚本从 Powershell 使用 --collectCoverageFrom 运行 Jest 测试时,转义引号和斜杠的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

尝试从通过 Intune MDM 执行的 powershell 脚本获取结果

Powershell 脚本无法使用任务计划程序通过 Outlook 发送电子邮件

如何通过使用标志或参数启动脚本来跳过部分 PowerShell 脚本

为啥“npm audit”CLI 命令不能从 Windows 10 中的 Powershell 运行?

为什么从任务栏关闭时,PowerShell脚本会卡住?

从Powershell中的文本文件中输入值