Có một số cách để tiếp cận điều này, mỗi cách đều có ưu và nhược điểm riêng:
request.main.filename
Từ http://nodejs.org/api/modules.html :
Khi một tệp được chạy trực tiếp từ Node, require.mainđược đặt thành của nó module. Điều đó có nghĩa là bạn có thể xác định xem tệp đã được chạy trực tiếp hay chưa bằng cách kiểm trarequire.main === module
Vì modulecung cấp một thuộc filenametính (thường tương đương với __filename), điểm vào của ứng dụng hiện tại có thể được lấy bằng cách kiểm tra require.main.filename.
Vì vậy, nếu bạn muốn có thư mục cơ sở cho ứng dụng của mình, bạn có thể làm:
var path = require('path');
var appDir = path.dirname(require.main.filename);
Ưu & Nhược điểm
Điều này sẽ hoạt động hiệu quả trong hầu hết thời gian, nhưng nếu bạn đang chạy ứng dụng của mình với trình khởi chạy như pm2 hoặc chạy thử nghiệm mocha , phương pháp này sẽ không thành công.
global.X
Node có một đối tượng không gian tên chung được gọi global- bất cứ thứ gì bạn đính kèm vào đối tượng này sẽ có sẵn ở mọi nơi trong ứng dụng của bạn. Vì vậy, trong index.js(hoặc app.jsbất kỳ tên tệp ứng dụng chính nào của bạn), bạn chỉ có thể xác định một biến toàn cục:
var path = require('path');
global.appRoot = path.resolve(__dirname);
require(appRoot + '/lib/moduleB/component2.js');
Ưu & Nhược điểm
Hoạt động nhất quán nhưng bạn phải dựa vào một biến toàn cục, có nghĩa là bạn không thể dễ dàng sử dụng lại các thành phần / v.v.
process.cwd ()
Điều này trả về thư mục làm việc hiện tại. Không đáng tin cậy chút nào, vì nó hoàn toàn phụ thuộc vào thư mục mà quy trình được khởi chạy từ :
$ cd /home/demo/
$ mkdir subdir
$ echo "console.log(process.cwd());" > subdir/demo.js
$ node subdir/demo.js
/home/demo
$ cd subdir
$ node demo.js
/home/demo/subdir
app-root-path
Để giải quyết vấn đề này, tôi đã tạo một mô-đun nút có tên là app-root-path . Cách sử dụng rất đơn giản:
var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');
Các app-root-path Module này sử dụng các kỹ thuật khác nhau để xác định đường dẫn gốc của ứng dụng, có tính đến các module được cài đặt trên toàn thế giới (ví dụ, nếu ứng dụng của bạn đang chạy trong /var/www/nhưng các module được cài đặt trong~/.nvm/v0.x.x/lib/node/ ). Nó sẽ không hoạt động 100% thời gian, nhưng nó sẽ hoạt động trong hầu hết các tình huống phổ biến.
Ưu & Nhược điểm
Hoạt động mà không cần cấu hình trong hầu hết các trường hợp. Cũng cung cấp một số phương pháp tiện lợi bổ sung (xem trang dự án). Vấn đề lớn nhất là nó sẽ không hoạt động nếu:
- Bạn đang sử dụng trình khởi chạy, như pm2
- VÀ , mô-đun không được cài đặt bên trong thư mục ứng dụng của bạn
node_modules(ví dụ: nếu bạn đã cài đặt nó trên toàn cầu)
Bạn có thể giải quyết vấn đề này bằng cách thiết lập một APP_ROOT_PATHbiến môi trường hoặc bằng cách gọi .setPath()mô-đun, nhưng trong trường hợp đó, có lẽ bạn nên sử dụng globalphương pháp này.
Biến môi trường NODE_PATH
Nếu bạn đang tìm cách xác định đường dẫn gốc của ứng dụng hiện tại, một trong những giải pháp trên có thể phù hợp nhất với bạn. Mặt khác, nếu bạn đang cố gắng giải quyết vấn đề tải mô-đun ứng dụng một cách đáng tin cậy, tôi thực sự khuyên bạn nên xem xét NODE_PATHbiến môi trường.
Hệ thống Mô-đun của Node tìm kiếm các mô-đun ở nhiều vị trí khác nhau. Một trong những vị trí này là bất cứ nơi nào process.env.NODE_PATHđiểm . Nếu bạn đặt biến môi trường này, thì bạn có thểrequire mô-đun với bộ tải mô-đun tiêu chuẩn mà không có bất kỳ thay đổi nào khác.
Ví dụ: nếu bạn đặt NODE_PATHthành /var/www/lib, những điều sau sẽ hoạt động tốt:
require('module2/component.js');
Một cách tuyệt vời để làm điều này là sử dụng npm:
"scripts": {
"start": "NODE_PATH=. node app.js"
}
Bây giờ bạn có thể bắt đầu ứng dụng của mình với npm startvà bạn là vàng. Tôi kết hợp điều này với mô-đun thực thi-nút-đường dẫn của mình , điều này ngăn việc vô tình tải ứng dụng mà không NODE_PATHđược thiết lập. Để kiểm soát nhiều hơn việc thực thi các biến môi trường, hãy xem checkenv .
Một gotcha: NODE_PATH phải được đặt bên ngoài ứng dụng nút. Bạn không thể làm điều gì đó như process.env.NODE_PATH = path.resolve(__dirname)vì trình tải mô-đun lưu danh sách các thư mục mà nó sẽ tìm kiếm trước khi ứng dụng của bạn chạy.
[thêm 4/6/16] Một mô-đun thực sự hứa hẹn khác cố gắng giải quyết vấn đề này là gợn sóng .