Yerel değişkenlere erişim ile node.js'de harici js dosyası yüklensin ve çalıştırılsın mı?


130

include('./path/to/file')Node.js'de basit bir komut türü yapmak kolay / mümkün mü?

Tek yapmak istediğim yerel değişkenlere erişim sağlamak ve bir komut dosyası çalıştırmak. İnsanlar genellikle basit bir merhaba dünyasından daha büyük olan node.js projelerini nasıl düzenler? (Tamamen işlevsel dinamik bir web sitesi)

Örneğin, aşağıdaki gibi dizinlere sahip olmak istiyorum:

/models

/views

... vb


Harici bir URL'den bir komut dosyası eklemek de mümkündür (yerel bir dosya yerine). Buraya bakın: pastebin.com/WkvHjGsG
Anderson Green

Yukarıdaki komut dosyası yalnızca komut dosyasıyla downloadedModulesaynı dizinde çağrılan bir klasör oluşturursanız doğru şekilde çalışır .
Anderson Green

Yanıtlar:


134

Sadece yap require('./yourfile.js');

Dışarıdan erişmek istediğiniz tüm değişkenleri genel değişkenler olarak bildirin. Yani yerine

var a = "hello" Olacak

GLOBAL.a="hello" ya da sadece

a = "hello"

Bu açıkça kötü. Küresel kapsamı kirletmek istemezsiniz. Bunun yerine, önerilen yöntem exportişlevlerinize / değişkenlerinize yöneliktir.

MVC modelini istiyorsanız Geddy'ye bir göz atın.


3
Bir yan not olarak .. Express'i seviyorum. MVC hakkında o kadar özel değilseniz, bunu da kontrol etmelisiniz.
Shripad Krishna

43
"Bu açıkça kötü" dediğinizde, "bu" neyi kastediyor?
Anderson Yeşil

1
@AndersonGreen - Değişkenleri küresel kapsamda koymak demek.
Tim

77
@AndersonGreen: Lütfen bunun kapsam belirlemeyle ilgili son derece zekice bir şaka olduğunu söyle ;-)
Dusty J

6
requireYolunuzun önüne şu şekilde bir şey koymazsanız, npm modüllerinizde nasıl görüneceğini öğrenmeme yardımcı oldu./
Dylan Valade

93

Modülleri tanımlamak için bir model olan CommonJS'yi anlamanız gerekir. GLOBAL kapsamını kötüye kullanmamalısınız, bu her zaman kötü bir şeydir, bunun yerine 'dışa aktarım' belirtecini kullanabilirsiniz, örneğin:

// circle.js

var PI = 3.14; // PI will not be accessible from outside this module

exports.area = function (r) {
  return PI * r * r;
};

exports.circumference = function (r) {
  return 2 * PI * r;
};

Ve modülümüzü kullanacak müşteri kodu:

// client.js

var circle = require('./circle');
console.log( 'The area of a circle of radius 4 is '
           + circle.area(4));

Bu kod, node.js dokümantasyon API'sinden alınmıştır:

http://nodejs.org/docs/v0.3.2/api/modules.html

Ayrıca, Rails veya Sinatra gibi bir şey kullanmak istiyorsanız, Express'i tavsiye ederim (URL'yi gönderemedim, Stack Overflow'da ayıp!)


64

Node için kod yazıyorsanız, Ivan tarafından açıklandığı gibi Node modüllerini kullanmak şüphesiz ki gidilecek yoldur.

Bununla birlikte, önceden yazılmış olan ve düğümün farkında olmayan JavaScript'i yüklemeniz gerekiyorsa, vmmodül bu yöntemdir (ve kesinlikle tercih edilir eval).

Örneğin, burada execfilekomut dosyasını pathya contextda küresel bağlamda değerlendiren benim modülüm:

var vm = require("vm");
var fs = require("fs");
module.exports = function(path, context) {
  var data = fs.readFileSync(path);
  vm.runInNewContext(data, context, path);
}

Ayrıca, yüklenen modüllerin require(…)genel bağlama erişimi olmadığını unutmayın .


1
Bu ipucu için teşekkürler. Gerçek kullanım durumu, modülleri adhoc yüklemeniz gerektiği zamandır. Merkezi bir hizmete kaydolan 1000 modülünüzün olduğu bir kayıt modeli gibi söyleyin. Hizmetinizde 1000 gerekli ifadesini yapmak yerine modülleri tarayıp tek tek yüklemek çok daha temiz ve daha iyi bir tasarım ...
Assaf Moldavsky

Düğüm dinamik gereksinimleri destekler, bu nedenle Düğüme duyarlı modüller dinamik olarak yüklenirken bu modeli kullanmak için hiçbir neden yoktur. Aslında, Düğümleri atladığı için orada kullanmak aktif olarak zararlıdır, bu require.cachenedenle tek bir dosya birden çok kez yüklenebilir.
David Wolever

Tamam, her birinin bir kayıt hizmetine kaydolduğu 1000 modülün olduğu durumda sunduğum durumu çözmek için, kayıt hizmetinde 1000 gerekli ifadesi olmadan önerdiğiniz şeyi nasıl kullanacaksınız?
Assaf Moldavsky

1
requireNormalde olduğu gibi: function loadService(name) { return require('./services/' + name); }hizmetleri listeleyin, ancak uygulama için mantıklıdır.
David Wolever

Doğru, ama bu kayıt hizmetindeki 1000 modülün hepsini bilmeniz gerektiği anlamına geliyor. Bu 1000 gerektiren ifadeye sahip olmaktan daha iyi değildir. Tüm fikir, kayıt hizmetinin tüm modülleri bilmemesi ve aslında onları önemsemesidir. Modüller kayıt hizmetine geçici olarak kaydedilir. bu mantıklı mı?
Assaf Moldavsky

7

Harici bir javascript dosyasının işlevlerini veya nesnelerini yüklemeyi planlıyorsanız, aşağıdaki kodu kullanarak bu bağlamı yükleyin - runInThisContext yöntemine dikkat edin:

var vm = require("vm");
var fs = require("fs");

var data = fs.readFileSync('./externalfile.js');
const script = new vm.Script(data);
script.runInThisContext();

// here you can use externalfile's functions or objects as if they were instantiated here. They have been added to this context. 

2
Çok fazla arama ve zıpladıktan sonra, bu teknik benim için çalıştı. Dosyalarım tarayıcının doğrudan kullanması ve bir değişken bildirmesi için yazılmıştır, örneğin: const aVar = {şey: 'a'}
lucsan

3

@Shripad'ın ve @Ivan'ın yanıtını genişleterek, Node.js'nin standart module.export işlevini kullanmanızı tavsiye ederim .

Sabitler için dosyanıza ( örneğin constants.js ), sabitleri şöyle yazarsınız:

const CONST1 = 1;
module.exports.CONST1 = CONST1;

const CONST2 = 2;
module.exports.CONST2 = CONST2;

Sonra bu sabitleri kullanmak istediğiniz dosyaya aşağıdaki kodu yazın:

const {CONST1 , CONST2} = require('./constants.js');

const { ... }Sözdizimini daha önce hiç görmediyseniz : bu yıkıcı görevdir .


0

Diriliş için özür dilerim. Node.js'de harici js dosyalarını yürütmek için child_process modülünü kullanabilirsiniz.

var child_process = require('child_process');

//EXECUTE yourExternalJsFile.js
child_process.exec('node yourExternalJsFile.js', (error, stdout, stderr) => {
    console.log(`${stdout}`);
    console.log(`${stderr}`);
    if (error !== null) {
        console.log(`exec error: ${error}`);
    }
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.