Çalışan bir node.js uygulamasından proje kökünü belirleme

Çalışan bir node.js işleminin kök dizinini belirlemek için process.cwd()den daha iyi bir yol var mı? Rails.root` eşdeğeri gibi bir şey, ancak Node.js için. Mümkün olduğunca öngörülebilir ve güvenilir bir şey arıyorum.

Çözüm

Bu konuya yaklaşmanın, her birinin kendi artıları ve eksileri olan çeşitli yolları vardır:

require.main.filename

adresinden alınmıştır:

Bir dosya doğrudan Node'dan çalıştırıldığında, require.main onun modülüne ayarlanır. Bu, bir dosyanın doğrudan çalıştırılıp çalıştırılmadığını require.main === module test ederek belirleyebileceğiniz anlamına gelir

module bir filename özelliği sağladığından (normalde __filename ile eşdeğerdir), mevcut uygulamanın giriş noktası require.main.filename kontrol edilerek elde edilebilir.

Yani uygulamanız için temel dizini istiyorsanız, bunu yapabilirsiniz:

var path = require('path');
var appDir = path.dirname(require.main.filename);

Artıları ve Eksileri

Bu çoğu zaman harika çalışacaktır, ancak uygulamanızı pm2 gibi bir başlatıcı ile çalıştırıyorsanız veya mocha testleri çalıştırıyorsanız, bu yöntem başarısız olacaktır.

global.X

Node'un global adında bir global isim alanı nesnesi vardır - bu nesneye eklediğiniz her şey uygulamanızın her yerinde kullanılabilir olacaktır. Dolayısıyla, index.js (veya app.js ya da ana uygulama dosyanızın adı her neyse) dosyanızda global bir değişken tanımlayabilirsiniz:

// index.js
var path = require('path');
global.appRoot = path.resolve(__dirname);

// lib/moduleA/component1.js
require(appRoot + '/lib/moduleB/component2.js');

Artıları ve Eksileri

Tutarlı bir şekilde çalışır, ancak küresel bir değişkene güvenmeniz gerekir, bu da bileşenleri / vb. kolayca yeniden kullanamayacağınız anlamına gelir.

process.cwd()

Bu, geçerli çalışma dizinini döndürür. Hiç güvenilir değildir, çünkü tamamen sürecin hangi dizinden başlatıldığına bağlıdır:

$ 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

Bu sorunu çözmek için app-root-path adında bir node modülü oluşturdum. Kullanımı basittir:

var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');

app-root-path](https://github.com/inxilpro/node-app-root-path)** modülü, global olarak yüklenmiş modülleri dikkate alarak uygulamanın kök yolunu belirlemek için birkaç farklı teknik kullanır (örneğin, uygulamanız /var/www/ içinde çalışıyorsa ancak modül ~/.nvm/v0.x.x/lib/node/ içinde yüklüyse). Her zaman %100 işe yaramayacaktır, ancak çoğu yaygın senaryoda işe yarayacaktır.

Artıları ve Eksileri

Çoğu durumda yapılandırma olmadan çalışır. Ayrıca bazı güzel ek kolaylık yöntemleri sağlar (proje sayfasına bakın). En büyük dezavantajı şu durumlarda çalışmamasıdır:

  • Pm2 gibi bir başlatıcı kullanıyorsunuz
  • VE**, modül uygulamanızın node_modules dizinine yüklenmemişse (örneğin, global olarak yüklediyseniz)

Bunu bir APP_ROOT_PATH çevresel değişkeni ayarlayarak ya da modül üzerinde .setPath() işlevini çağırarak aşabilirsiniz, ancak bu durumda global yöntemini kullanmanız muhtemelen daha iyi olacaktır.

NODE_PATH çevresel değişkeni

Mevcut uygulamanın kök yolunu belirlemenin bir yolunu arıyorsanız, yukarıdaki çözümlerden biri muhtemelen sizin için en iyi sonucu verecektir. Öte yandan, uygulama modüllerini güvenilir bir şekilde yükleme sorununu çözmeye çalışıyorsanız, NODE_PATH çevresel değişkenine bakmanızı şiddetle tavsiye ederim.

Node'un Modüller sistemi çeşitli konumlardaki modülleri arar. Bu konumlardan biri process.env.NODE_PATHin işaret ettiği yerdir. Bu çevresel değişkeni ayarlarsanız, başka herhangi bir değişiklik yapmadan standart modül yükleyici ile modülleri gerektirebilirsiniz.

Örneğin, NODE_PATH değerini /var/www/lib olarak ayarlarsanız, aşağıdakiler gayet iyi çalışacaktır:

require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js

Bunu yapmanın harika bir yolu npm kullanmaktır:

"scripts": {
    "start": "NODE_PATH=. node app.js"
}

Artık uygulamanızı npm start ile başlatabilirsiniz ve altın değerindesiniz. Bunu enforce-node-path modülümle birleştiriyorum, bu da uygulamanın NODE_PATH ayarlanmadan yanlışlıkla yüklenmesini önlüyor. Çevresel değişkenleri zorlama konusunda daha fazla kontrol için checkenv'e bakın.

Bir sorun var: NODE_PATH node uygulamasının dışında** ayarlanmalıdır. Process.env.NODE_PATH = path.resolve(__dirname)` gibi bir şey yapamazsınız çünkü modül yükleyici, uygulamanız çalışmadan önce arayacağı dizinlerin listesini önbelleğe alır.

[added 4/6/16] Bu sorunu çözmeye çalışan gerçekten umut verici bir başka modül de wavy.

Yorumlar (22)

__dirname global değildir; mevcut modül için yereldir, bu nedenle her dosyanın kendi yerel, farklı değeri vardır.

Çalışan sürecin kök dizinini istiyorsanız, muhtemelen process.cwd() kullanmak istersiniz.

Öngörülebilirlik ve güvenilirlik istiyorsanız, muhtemelen belirli bir ortam değişkeninin ayarlanmasını uygulamanızın bir gerekliliği haline getirmeniz gerekir. Uygulamanız MY_APP_HOME (Veya her neyse) arar ve eğer oradaysa ve uygulama o dizinde mevcutsa, o zaman her şey yolundadır. Eğer tanımlanmamışsa veya dizin uygulamanızı içermiyorsa, kullanıcıdan değişkeni oluşturmasını isteyen bir hata ile çıkmalıdır. Bir yükleme işleminin parçası olarak ayarlanabilir.

Ortam değişkenlerini node'da process.env.MY_ENV_VARIABLE gibi bir şeyle okuyabilirsiniz.

Yorumlar (2)

1- Proje kök dizininde settings.js adında bir dosya oluşturun

2- Bu dosyanın içine şu kodu ekleyin

module.exports = {
    POST_MAX_SIZE : 40 , //MB
    UPLOAD_MAX_FILE_SIZE: 40, //MB
    PROJECT_DIR : __dirname
};

3- node_modules içinde "settings" adında yeni bir modül oluşturun ve index.js modülünün içine bu kodu yazın:

module.exports = require("../../settings");

4- ve proje dizininizi istediğiniz zaman sadece

var settings = require("settings");
settings.PROJECT_DIR; 

bu şekilde tüm proje dizinleri bu dosyaya göre olacaktır ;)

Yorumlar (9)