Déterminer le répertoire de travail de la ligne de commande lors de l'exécution du script bin de nœud

120

Je crée une interface de ligne de commande de nœud. Il est installé globalement et utilise un fichier bin pour s'exécuter.

Je prévois d'ouvrir une fenêtre de commande dans le répertoire racine des fichiers sur lesquels je travaille, puis d'exécuter simplement la commande, mais je n'ai pas pu déterminer le répertoire de travail actuel car il process.cwd()renvoie le répertoire du package de nœuds. J'ai d'abord supposé que puisque le code est exécuté en utilisant un fichier batch comme wrapper (c'est ainsi que les fichiers bin peuvent s'exécuter sans nœud au début), il est impossible mais coffee-script parvient à le faire. J'ai jeté un coup d'œil à la source de coffee-script mais je n'ai pas pu la suivre (pas assez expérimenté).

Pour le tester par vous-même, créez un package avec ce fichier package.json:

{
  "name": "test-package",
  "version": "1.0.0",
  "bin": {
    "test-package":  "./bin/test-package"
  },
  "main": "/lib/test"
}

ce fichier de package de test dans bin:

#!/usr/bin/env node

var path = require('path');
var fs   = require('fs');
var lib  = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');

require(lib + '/test');

Quelqu'un pourrait-il faire la lumière là-dessus.

puis essayez d'obtenir le répertoire de ligne de commande dans lib / test.

Daniel Chatfield
la source

Réponses:

196
  • process.cwd() renvoie le répertoire dans lequel la commande a été exécutée (pas le répertoire du package de nœuds) s'il n'a pas été modifié par 'process.chdir' à l'intérieur de l'application.
  • __filename renvoie le chemin absolu du fichier où il est placé.
  • __dirnamerenvoie le chemin absolu vers le répertoire de __filename.

Si vous devez charger des fichiers à partir du répertoire de votre module, vous devez utiliser des chemins relatifs.

require('../lib/test');

au lieu de

var lib  = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');

require(lib + '/test');

Il est toujours relatif au fichier d'où il est appelé et ne dépend pas du répertoire de travail actuel.

Vadim Baryshev
la source
2
Après process.chdir(), y a-t-il un moyen d'obtenir l'original?
reergymerej
@reergymerej Vous voudrez probablement stocker cwd avant d'exécuter chdir () (par exemple, var originalCwd = process.cwd();exécutez votre process.chdir(), et vous pourrez ensuite revenir à l'original).
Pivot du
est ../lib/testportable?
Sebastian
Non. Ce n'est pas une solution portable car Windows utilise des barres obliques inverses. Donc, si vous essayez de l'exécuter dans Windows, cela ne fonctionnera pas.
zachdyer le
1
En fait, pour NodeJS, c'est la même chose. Même sous Windows, vous pouvez facilement exiger des chemins relatifs à la manière Unix. Donc, ../lib/testc'est portable, alors que l'homologue Windows ..\lib\testn'est pas ...
Christian Ulbrich
48

Répertoire de travail actuel

Pour obtenir le répertoire de travail actuel, vous pouvez utiliser:

process.cwd()

Cependant, sachez que certains scripts, notamment gulp, modifieront le répertoire de travail actuel avec process.chdir().

Chemin du module de nœud

Vous pouvez obtenir le chemin du module actuel avec:

  • __filename
  • __dirname

Répertoire d'origine (où la commande a été lancée)

Si vous exécutez un script à partir de la ligne de commande et que vous voulez le répertoire d'origine à partir duquel le script a été exécuté, quel que soit le répertoire dans lequel le script fonctionne actuellement, vous pouvez utiliser:

process.env.INIT_CWD

Répertoire d'origine, lors de l'utilisation de scripts NPM

Il est parfois souhaitable d'exécuter un script NPM dans le répertoire courant, plutôt qu'à la racine du projet.

Cette variable est disponible dans les scripts de package npm sous la forme:

$INIT_CWD.

Vous devez exécuter une version récente de NPM. Si cette variable n'est pas disponible, assurez-vous que NPM est à jour.

Cela vous permettra d'accéder au chemin actuel dans votre package.json, par exemple:

scripts: {
  "customScript": "gulp customScript --path $INIT_CWD"
}
superluminaire
la source
process.env.INIT_CWDrenvoie le dir depackage.json
vaughan
2
Attention, $ INIT_CWD ne fonctionne que sous Linux. Pour Windows, vous devrez utiliser% INIT_CWD%. Je pense que ce problème peut être résolu en utilisant npmjs.com/package/cross-env , mais je ne l'ai pas essayé moi
Stephanie
3

Sinon, si vous souhaitez obtenir uniquement le répertoire courant du script NodeJS actuel, vous pouvez essayer quelque chose de simple comme celui-ci. Notez que cela ne fonctionnera pas dans le Node CLI lui-même:

var fs = require('fs'),
    path = require('path');

var dirString = path.dirname(fs.realpathSync(__filename));

// output example: "/Users/jb/workspace/abtest"
console.log('directory to start walking...', dirString);
John Paul Barbagallo
la source
3

path.resolve('.')est également une option fiable et propre, car nous avons presque toujours require('path'). Il vous donnera le chemin absolu du répertoire à partir duquel il est appelé.

sziraqui
la source
0

Voici ce qui a fonctionné pour moi:

console.log(process.mainModule.filename);
Etienne Martin
la source