il modello glob npm non corrisponde alle sottodirectory

Nel mio package.json , ho un blocco di script che utilizza **/*Test.js per abbinare i file. Quando vengono eseguiti tramite npm , non corrispondono alle sottodirectory di più di un livello. Quando vengono eseguiti direttamente dalla riga di comando, funzionano come previsto.

Qualcuno può spiegare cosa sta succedendo e fornire una soluzione alternativa?

package.json

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

Esecuzione

 % npm run test > [email protected] 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 

Soluzione

Cambia i tuoi script in modo che ciò che passi a Mocha sia protetto dall’espansione dalla shell:

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

Notare le virgolette singole attorno al parametro dato a mocha .

Spiegazione

Questo problema è risolvibile senza ricorrere a strumenti esterni. La causa principale del tuo problema è che npm usa sh come shell che eseguirà i tuoi comandi di script.

È in modo schiacciante il fatto che quando un processo * nix avvia una shell, inizierà a meno che non ci sia qualcosa che gli dice di fare altrimenti. La preferenza della shell impostata per gli accessi non costituisce un modo per “dirlo diversamente”. Quindi se hai, per esempio, zsh come shell di login, non implica che npm userà zsh .

Quelle implementazioni di sh che non includono estensioni oltre a ciò che dovrebbe fornire non comprendono il glob nel modo in cui lo si desidera. Per quanto posso dire, è interpretato come * . Tuttavia, Mocha interpreta i percorsi passati ad esso utilizzando la sua implementazione JavaScript di glob. Così puoi risolvere il problema proteggendo i tuoi glob da essere interpretati da sh . Considera il seguente package.json :

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

Lo script della shell è solo così da poter verificare quale shell sta eseguendo lo script. Se lo esegui, dovresti vedere sh .

Ora, dato il seguente albero:

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

Con tutti i file a.js e b.js che it(__filename); contengono it(__filename); . Ottieni i seguenti risultati:

 $ npm run bad > [email protected] 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 > [email protected] 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 

È ansible allineare il comando find con l’opzione -name negli script per sostituire la syntax globbing estesa fornita da zsh.

Nel tuo caso, il comando sarebbe:

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

Puoi realisticamente omettere la parte -type f se sei sicuro di non mettere mai “Test.js” nel nome di una directory. (Un’assunzione sicura, molto probabilmente, ma l’ho inclusa per completezza)

L’espansione glob è effettivamente fatta dalla tua shell ed è per questo che funziona dalla riga di comando.

Puoi fare mocha --recursive e puntare alla directory di test.