Визначте робочий каталог командного рядка під час запуску сценарію bin node


120

Я створюю інтерфейс командного рядка вузла. Він встановлений у всьому світі та використовує файл bin для виконання.

Я планую відкрити вікно команд у кореневому каталозі файлів, над якими я працюю, а потім просто запустити команду, проте я не зміг визначити поточний робочий каталог, як process.cwd()повертає каталог пакету вузлів. Я спочатку припускав, що оскільки код виконується з використанням пакетного файлу як обгортки (саме так бінські файли можуть виконуватись без вузла на початку), то це неможливо, але кава-скрипт вдається це зробити. Я подивився джерело сценарію кави, але не зміг його дотримуватися (недостатньо досвідчений).

Щоб перевірити це на собі, створіть пакет із цим файлом package.json:

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

цей файл тестового пакета у кошику:

#!/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');

Хтось може пролити на це світло.

а потім спробуйте отримати каталог командного рядка всередині lib / test.

Відповіді:


196
  • process.cwd() повертає каталог, де виконується команда (не каталог пакету вузлів), якщо вона не була змінена 'process.chdir' всередині програми.
  • __filename повертає абсолютний шлях до файлу, де він розміщений.
  • __dirnameповертає абсолютний шлях до каталогу __filename.

Якщо вам потрібно завантажити файли з каталогу вашого модуля, вам потрібно використовувати відносні шляхи.

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

замість

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

require(lib + '/test');

Це завжди відносно файлу, звідки він дзвонив, і не залежить від поточного режиму роботи.


2
Після process.chdir(), чи є спосіб отримати оригінал?
reergymerej

@reergymerej Ви, ймовірно, захочете спершу зберігати cwd перед виконанням chdir () (наприклад, var originalCwd = process.cwd();потім виконати свій файл process.chdir(), а потім можете повернутися до оригіналу).
Поворот

є ../lib/testпортативним?
Себастьян

Ні. Це не портативне рішення, тому що Windows використовує зворотні риси. Тож якщо ви спробуєте запустити його у Windows, це не вийде.
zachdyer

1
Насправді для NodeJS це все одно. Навіть у Windows можна зручно вимагати відносних шляхів у Unix. Так ../lib/testпортативно, тоді як колега Windows ..\lib\test- це не ...
Крістіан Ульбріх,

48

Поточний робочий каталог

Щоб отримати поточний робочий каталог, ви можете використовувати:

process.cwd()

Однак майте на увазі, що деякі сценарії, особливо глотком, змінять поточну робочу директорію process.chdir().

Шлях модуля вузла

Ви можете отримати шлях поточного модуля за допомогою:

  • __filename
  • __dirname

Оригінальний каталог (де команда була ініційована)

Якщо ви запускаєте скрипт з командного рядка, і ви хочете, щоб оригінальний каталог, з якого був запущений скрипт, незалежно від того, в якому каталозі сценарій працює, ви можете використовувати:

process.env.INIT_CWD

Оригінальний каталог під час роботи зі сценаріями NPM

Іноді бажано запустити сценарій NPM у поточному каталозі, а не в корені проекту.

Ця змінна доступна у сценаріях пакету npm як:

$INIT_CWD.

Ви повинні мати останню версію NPM. Якщо ця змінна недоступна, переконайтеся, що NPM оновлений.

Це дозволить отримати доступ до поточного шляху у пакеті.json, наприклад:

scripts: {
  "customScript": "gulp customScript --path $INIT_CWD"
}

process.env.INIT_CWDповертає режpackage.json
воган

2
Зауважте, $ INIT_CWD працює лише в Linux. Для Windows вам доведеться використовувати% INIT_CWD%. Я думаю, що цю проблему можна подолати за допомогою npmjs.com/package/cross-env , але я сама не пробувала цього
Стефані

3

Крім того, якщо ви хочете отримати виключно поточний каталог поточного сценарію NodeJS, ви можете спробувати щось таке, як це. Зауважте, що це не буде працювати в самому CLI-вузлі:

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);

3

path.resolve('.')- це також надійний і чистий варіант, адже ми майже завжди require('path'). Це дасть вам абсолютний шлях до каталогу, звідки він викликаний.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.