Ç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.
Bu konuya yaklaşmanın, her birinin kendi artıları ve eksileri olan çeşitli yolları vardır:
http://nodejs.org/api/modules.html adresinden alınmıştır:
Bir dosya doğrudan Node'dan çalıştırıldığında,
require.main
onunmodü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
birfilename
ö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);
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.
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');
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.
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
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.
Ç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:
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.
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_PATH
in 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.
__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.
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 ;)