Xác định thư mục làm việc dòng lệnh khi chạy tập lệnh bin node


120

Tôi đang tạo giao diện dòng lệnh nút. Nó được cài đặt toàn cầu và sử dụng tệp bin để thực thi.

Tôi dự định mở một cửa sổ lệnh tại thư mục gốc của các tệp tôi đang làm việc và sau đó chỉ cần chạy lệnh, tuy nhiên tôi không thể xác định thư mục làm việc hiện tại như process.cwd()đang trả về thư mục của gói nút. Ban đầu tôi giả định rằng vì mã đang được thực thi bằng cách sử dụng tệp loạt làm trình bao bọc (đó là cách tệp bin có thể thực thi mà không có nút ở đầu) nên điều đó là không thể nhưng coffee-script quản lý để làm điều đó. Tôi đã xem qua nguồn coffee-script nhưng không theo được (chưa đủ kinh nghiệm).

Để tự kiểm tra nó, hãy tạo một gói với tệp package.json này:

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

tệp gói thử nghiệm này trong thùng:

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

Bất cứ ai có thể làm sáng tỏ điều này.

và sau đó thử và lấy thư mục dòng lệnh bên trong lib / test.

Câu trả lời:


196
  • process.cwd() trả về thư mục nơi lệnh đã được thực thi (không phải thư mục của gói nút) nếu nó không bị thay đổi bởi 'process.chdir' bên trong ứng dụng.
  • __filename trả về đường dẫn tuyệt đối đến tệp nơi nó được đặt.
  • __dirnametrả về đường dẫn tuyệt đối đến thư mục của __filename.

Nếu bạn cần tải tệp từ thư mục mô-đun của mình, bạn cần sử dụng đường dẫn tương đối.

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

thay vì

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

require(lib + '/test');

Nó luôn liên quan đến tệp nơi nó được gọi và không phụ thuộc vào dir công việc hiện tại.


2
Sau khi process.chdir(), có cách nào để lấy lại bản gốc?
reergymerej

@reergymerej Có thể bạn sẽ muốn lưu trữ cwd trước khi thực thi chdir () (ví dụ: var originalCwd = process.cwd();sau đó thực thi your process.chdir(), và bạn có thể quay lại bản gốc sau đó).
Swivel

../lib/testxách tay?
Sebastian

Không. Nó không phải là một giải pháp di động vì các cửa sổ sử dụng dấu gạch chéo ngược. Vì vậy, nếu bạn cố gắng chạy nó trong windows, nó sẽ không hoạt động.
zachdyer 14/09/18

1
Thực ra đối với NodeJS thì điều này cũng giống nhau. Ngay cả trên Windows, bạn có thể thuận tiện yêu cầu các đường dẫn tương đối theo cách Unix. Vì vậy, ../lib/testcó thể di động, trong khi các đối tác của Windows ..\lib\testkhông phải là ...
Christian Ulbrich

48

Thư mục làm việc hiện tại

Để có được thư mục làm việc hiện tại, bạn có thể sử dụng:

process.cwd()

Tuy nhiên, hãy lưu ý rằng một số tập lệnh, đặc biệt là gulp, sẽ thay đổi thư mục làm việc hiện tại với process.chdir().

Đường dẫn mô-đun nút

Bạn có thể lấy đường dẫn của mô-đun hiện tại bằng:

  • __filename
  • __dirname

Thư mục gốc (nơi lệnh được bắt đầu)

Nếu bạn đang chạy một tập lệnh từ dòng lệnh và bạn muốn thư mục gốc mà từ đó tập lệnh được chạy, bất kể tập lệnh hiện đang hoạt động trong thư mục nào, bạn có thể sử dụng:

process.env.INIT_CWD

Thư mục gốc, khi làm việc với tập lệnh NPM

Đôi khi bạn nên chạy một tập lệnh NPM trong thư mục hiện tại, thay vì thư mục gốc của dự án.

Biến này có sẵn bên trong các tập lệnh gói npm như:

$INIT_CWD.

Bạn phải đang chạy phiên bản NPM gần đây. Nếu không có sẵn biến này, hãy đảm bảo NPM được cập nhật.

Điều này sẽ cho phép bạn truy cập đường dẫn hiện tại trong package.json của bạn, ví dụ:

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

process.env.INIT_CWDtrả lại đồng dir củapackage.json
vaughan

2
Hãy chú ý, $ INIT_CWD chỉ hoạt động trên Linux. Đối với Windows, bạn sẽ phải sử dụng% INIT_CWD%. Tôi nghĩ rằng vấn đề này có thể được khắc phục bằng cách sử dụng npmjs.com/package/cross-env , nhưng tôi đã không thử nó bản thân mình
Stephanie

3

Ngoài ra, nếu bạn chỉ muốn lấy thư mục hiện tại của tập lệnh NodeJS hiện tại, bạn có thể thử một cái gì đó đơn giản như thế này. Lưu ý rằng điều này sẽ không hoạt động trong chính Node 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('.')cũng là một lựa chọn đáng tin cậy và sạch sẽ, bởi vì chúng tôi hầu như luôn luôn require('path'). Nó sẽ cung cấp cho bạn đường dẫn tuyệt đối của thư mục từ nơi nó được gọi.


0

Đây là những gì đã làm việc cho tôi:

console.log(process.mainModule.filename);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.