Değişkenler Node.js'deki dosyalar arasında paylaşılsın mı?


126

İşte 2 dosya:

// main.js
require('./modules');
console.log(name); // prints "foobar"

// module.js
name = "foobar";

"Var" olmadığında işe yarıyor. Ama sahip olduğumda:

// module.js
var name = "foobar";

name, main.js'de tanımsız olacaktır.

Global değişkenlerin kötü olduğunu duydum ve referanslardan önce "var" kullanmanız daha iyi olur. Ancak bu, küresel değişkenlerin iyi olduğu bir durum mu?

Yanıtlar:


184

Küresel değişkenler neredeyse hiçbir zaman iyi bir şey değildir (belki bir veya iki istisna olabilir ...). Bu durumda, gerçekten sadece "ad" değişkeninizi dışa aktarmak istediğiniz gibi görünüyor. Örneğin,

// module.js
var name = "foobar";
// export it
exports.name = name;

Ardından, main.js'de ...

//main.js
// get a reference to your required module
var myModule = require('./module');

// name is a member of myModule due to the export above
var name = myModule.name;

1
küresel değişkenler kötü - buna tamamen katılıyorum. Ama modülün bir değişkene bağımlılığı olabilir. Bu değişkeni diğer js dosyasına need işlevi aracılığıyla geçirmenin bir yolu var mı?
appsthattermatter

1
@ jjoe64 Ne demek istediğini anladığımdan emin değilim. exportsNesne aracılığıyla istediğiniz herhangi bir değeri etkin bir şekilde paylaşabilirsiniz .
jmar777

7
OP, bir değişkenin main.js'de tanımlanıp tanımlanamayacağını ve daha sonra module.js'de kullanılıp kullanılamayacağını soruyor. Tekrar tekrar kullanılan yolları tanımlamak için aynı gereksinime sahibim.
designermonkey

4
@Designermonkey Bu durumda, belirli bir dosyada () 'd gerektirebilecek bu tür değerlere sahip bir yapılandırma nesnesine sahip olmanız muhtemelen daha iyidir. O Not olabilir sadece bunu global.foo = 'bar've daha sonra erişim fooher yerde istiyorum ... ama benim asıl cevap, söz konusu gibi neredeyse iyi bir şey olmadı.
jmar777

Bunun için teşekkürler, bunu nasıl yapacağımı buldum ve bu bir tedavi oldu. Doğru fikre sahip olduğumu doğruladığınız için teşekkürler :)
designermonkey

37

varEn iyi seçeneğin global olduğu bir senaryo bulamıyorum , elbette bir tane olabilir, ancak bu örneklere bir göz atın ve aynı şeyi başarmanın daha iyi bir yolunu bulabilirsiniz:

Senaryo 1: Öğeleri yapılandırma dosyalarına koyun

Uygulama genelinde aynı olan bir değere ihtiyacınız var, ancak ortama (üretim, geliştirme veya test), örneğin posta türüne bağlı olarak değişiyor, ihtiyacınız olacak:

// File: config/environments/production.json
{
    "mailerType": "SMTP",
    "mailerConfig": {
      "service": "Gmail",
      ....
}

ve

// File: config/environments/test.json
{
    "mailerType": "Stub",
    "mailerConfig": {
      "error": false
    }
}

(dev için de benzer bir yapılandırma yapın)

Hangi yapılandırmanın yükleneceğine karar vermek için bir ana yapılandırma dosyası oluşturun (bu, uygulamanın her yerinde kullanılacaktır)

// File: config/config.js
var _ = require('underscore');

module.exports = _.extend(
    require(__dirname + '/../config/environments/' + process.env.NODE_ENV + '.json') || {});

Ve şimdi şu gibi verileri alabilirsiniz :

// File: server.js
...
var config = require('./config/config');
...
mailer.setTransport(nodemailer.createTransport(config.mailerType, config.mailerConfig));

Senaryo 2: Bir sabitler dosyası kullanın

// File: constants.js
module.exports = {
  appName: 'My neat app',
  currentAPIVersion: 3
};

Ve bu şekilde kullan

// File: config/routes.js

var constants = require('../constants');

module.exports = function(app, passport, auth) {
  var apiroot = '/api/v' + constants.currentAPIVersion;
...
  app.post(apiroot + '/users', users.create);
...

Senaryo 3: Verileri almak / ayarlamak için bir yardımcı işlev kullanın

Bunun büyük bir hayranı değil, ama en azından 'adın' kullanımını takip edebilir (OP'nin örneğini göstererek) ve doğrulamaları yerine getirebilirsiniz.

// File: helpers/nameHelper.js

var _name = 'I shall not be null'

exports.getName = function() {
  return _name;
};

exports.setName = function(name) {
  //validate the name...
  _name = name;
};

Ve kullan

// File: controllers/users.js

var nameHelper = require('../helpers/nameHelper.js');

exports.create = function(req, res, next) {
  var user = new User();
  user.name = req.body.name || nameHelper.getName();
  ...

Global olmaktan başka bir çözüm olmadığında bir kullanım durumu olabilir var, ancak node.js kullanmaya başlıyorsanız (daha önce olduğu gibi) genellikle uygulamanızdaki verileri bu senaryolardan birini kullanarak paylaşabilirsiniz. oradaki verileri işleme şeklinizi organize etmek için, çünkü çok hızlı bir şekilde dağınık olabilir.


Senaryo 2'yi beğendim, ancak bu değerler inşa konuştuktan sonra değiştirilebilir mi? çoğu zaman yaptığımız gibi, npm run build. Veya inşa ettikten sonra değerleri değiştirmenin bir yolunu biliyor musunuz?
Kashif Ullah

@KashifUllah, yorumunuza sadece verilen bilgilerle cevap verip veremeyeceğimi bilmiyorum, siteye yeni bir soru eklemek isteyebilirsiniz
Felipe Pereira

16

Birden fazla değişkeni paylaşmamız gerekirse aşağıdaki formatı kullanın

//module.js
   let name='foobar';
   let city='xyz';
   let company='companyName';

   module.exports={
    name,
    city,
    company
  }

kullanım

  // main.js
    require('./modules');
    console.log(name); // print 'foobar'

2
ilk noktada ortaya çıkabilecek kafa karışıklığını ortadan kaldırmak için sadece kısa bir not: module.exports kullanılması gereken şeydir! js dosyanızın adı ne olursa olsun (örn: global.js). modül, genel kapsamda bulunan bir düğüm nesnesidir! [dolayısıyla global.js içinde module.exports = ..... kullanıyoruz]
Mohamed Allal

"let" i kaldırırsanız başarılı olur ve "module.exports .." dosyasına gerek yoktur
Ahmad

6

Paylaşılmasını istediğiniz herhangi bir değişkeni tek bir nesne olarak kaydedin. Ardından, değişkene nesne başvurusu aracılığıyla erişebilmesi için onu yüklü modüle iletin.

// main.js
var myModule = require('./module.js');
var shares = {value:123};

// Initialize module and pass the shareable object
myModule.init(shares);

// The value was changed from init2 on the other file
console.log(shares.value); // 789

Diğer dosyada ..

// module.js
var shared = null;

function init2(){
    console.log(shared.value); // 123
    shared.value = 789;
}

module.exports = {
    init:function(obj){
        // Save the shared object on current module
        shared = obj;

        // Call something outside
        init2();
    }
}

1

var anahtar sözcüğü ile veya anahtar sözcük olmadan bildirilen bir değişken genel nesneye eklenmiştir. Bu, değişkenleri var anahtar sözcüğü olmadan bildirerek Düğümde genel değişkenler oluşturmanın temelidir. Var anahtar sözcüğü ile bildirilen değişkenler bir modül için yerel olarak kalır.

daha fazla bilgi için bu makaleye bakın - https://www.hacksparrow.com/global-variables-in-node-js.html


3
Bu parçalar çelişiyor mu? 1) "var anahtar sözcüğü ile veya anahtar sözcüğü olmadan bildirilen bir değişken genel nesneye eklenmiştir." ve 2) "var anahtar sözcüğü ile bildirilen değişkenler bir modül için yerel olarak kalır."
BaldEagle

1

Farklı bir globalgörüşle, kodunuzu yayınlayacaksanız değişkenlerin en iyi seçenek olabileceğini düşünüyorum npm, çünkü tüm paketlerin kodunuzun aynı sürümünü kullandığından emin olamazsınız. Dolayısıyla, bir dosyayı dışa aktarmak için bir dosya kullanıyorsanızsingleton , nesneyi , burada sorunlara neden olur.

Seçebilirsiniz global, require.mainya da dosyalar arasında paylaşılır başka nesneler.

Lütfen bana daha iyi çözümler olup olmadığını söyle.

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.