npm glob模式不匹配子目录

在我的package.json ,我有一个使用**/*Test.js来匹配文件的脚本块。 当通过npm ,它们不匹配超过一个级别的子目录。 当直接在命令行执行时,它们按预期工作。

任何人都可以解释发生了什么,并提供一个解决方法或解决scheme?

package.json

 { "name": "immutable-ts", "scripts": { "test": "echo mocha dist/**/*Test.js", } } 

执行

 % npm run test > immutable-ts@0.0.0 test:unit .../immutable-ts > echo mocha dist/**/*Test.js mocha dist/queue/QueueTest.js dist/stack/StackTest.js % echo mocha dist/**/*Test.js mocha dist/queue/QueueTest.js dist/stack/StackTest.js dist/tree/binary/BinaryTreeTest.js % ls dist/**/* dist/collections.js dist/queue/QueueTest.js dist/tree/binary/BinaryTree.js dist/immutable.js.map dist/stack/Stack.js.map dist/tree/binary/BinaryTreeTest.js.map dist/immutable.js dist/stack/Stack.js dist/tree/binary/BinaryTreeTest.js dist/queue/Queue.js.map dist/stack/StackTest.js.map dist/queue/Queue.js dist/stack/StackTest.js dist/collections.js.map dist/queue/QueueTest.js.map dist/tree/binary/BinaryTree.js.map 

改变您的脚本,以便您传递给Mocha的内容不受shell的影响:

 "scripts": { "test": "mocha 'dist/**/*Test.js'", } 

请注意mocha给出的参数的单引号。

说明

这个问题是可以解决的,而不是诉诸外部工具。 你的问题的根本原因是npm使用sh作为运行脚本命令的shell。

绝大多数情况是,当一个* nix进程启动一个shell时,除非有其他的事情告诉它,否则就会启动。 您为login设置的shell首选项并不构成“另行说明”的方法。 所以如果你有,比如zsh作为你的loginshell,那么npm将不会使用zsh

那些不包含任何超出sh应该提供的扩展名的sh实现不能以你想要的方式理解** glob。 据我所知,它被解释为* 。 但是, Mocha使用它的一个JavaScript实现来解释传递给它的path。 所以你可以通过保护你的球体不被sh解释来解决这个问题。 考虑下面的package.json

 { "name": "immutable-ts", "scripts": { "bad": "mocha test/**/*a.js", "good": "mocha 'test/**/*a.js'", "shell": "echo $0" } } 

shell脚本就是这样,我们可以检查shell运行的脚本。 如果你运行它,你应该看到sh

现在,给出以下树:

 test/ ├── a.js ├── b.js ├── x │  ├── a │  │  ├── a.js │  │  └── b.js │  ├── a.js │  └── b │  └── a.js └── y ├── a.js └── q 

所有包含it(__filename); a.jsb.js文件it(__filename); 。 您会得到以下结果:

 $ npm run bad > immutable-ts@ bad /tmp/t2 > mocha test/**/*a.js - /tmp/t2/test/x/a.js - /tmp/t2/test/y/a.js 0 passing (6ms) 2 pending $ npm run good > immutable-ts@ good /tmp/t2 > mocha 'test/**/*a.js' - /tmp/t2/test/a.js - /tmp/t2/test/x/a.js - /tmp/t2/test/x/a/a.js - /tmp/t2/test/x/b/a.js - /tmp/t2/test/y/a.js 0 passing (5ms) 5 pending 

您可以在脚本中使用-name选项内联find命令来replacezsh提供的扩展的通配符语法。

在你的情况下,该命令将是:

 mocha `find dist -type f -name '*Test.js'` 

如果你确信你永远不会把“Test.js”放在目录名中,你可以切实地省略-type f部分。 (一个安全的假设,最有可能的,但我包括它完整性)

全局扩展实际上是由你的shell完成的,这就是为什么它从命令行工作。

你可以做mocha --recursive并指向你的testing目录。