Экспорт модуля node.js, как использовать данные среди всех модулей? - PullRequest
0 голосов
/ 21 октября 2018

Я хотел бы использовать обновленные (и только тогда) глобальные переменные среди всех узловых модулей.Как это сделать?Вопросы в коде.

app.js

var data = 'data';

var global = require('glob.js')(data);
// here we are require your globals variables and we corectly 'set them'

console.log(globals.glob1);
// we can use them here

glob.js

module.exports  = function(data)
{
    var globs = {
        glob1 : data.toLowerCase(),
        glob2 : data.toUpperCase()
    }
    return globs;
}

мод.js

var global = require('glob.js'); // I require globals but they are not set...

function funct(someOtherData, someMoreData)
{
    var test = global.glob1;
    console.log(test);
    // why I can't use globals here ? How can I use corectly set globals (globals need to be updated first - app.js, then ALL other modules should be able to use correctly set globals)?
}

module.export = funct;

Ответы [ 3 ]

0 голосов
/ 21 октября 2018

Вы можете использовать идентификатор переменной global. для установки глобальных переменных в NodeJS вместо var, например:

app.js

var data = 'data';

var glob = require('./glob.js');
glob(data);
// here we are require your globals variables and we corectly 'set them'

console.log(global.gl.glob1);
var mod = require('./mod.js');
mod();
// we can use them here 

glob.js

module.exports  = function(data)
{
    console.log("setting globals");
    global.gl = {
        glob1 : '1' + data,
        glob2 : '2' + data
    }
    // return global.gl; // can be removed 
}

mod.js

function funct(someOtherData, someMoreData)
{
    var test = global.gl.glob1;
    console.log(test);
    test = global.gl.glob2;
    console.log(test);
    // why I can't use globals here ? How can I use corectly set globals (globals need to be updated first - app.js, then ALL other modules should be able to use correctly set globals)?
}

module.exports = funct;

Как вы можете видеть в glob.js , я переключился на var globs = на global.gl =, а затем в mod.js использовал его как global.gl.

Запуск app.js выходы:

setting globals
1data // From app.js
1data // From mod.js imported in app.js
2data // From mod.js imported in app.js
0 голосов
/ 21 октября 2018

Для ответа прокрутите вниз до раздела TLDR ниже, но продолжайте читать, чтобы понять, почему.

Part1 - разница между функцией и вызовом функции

Ваша первая ошибка заключается в том, что вы экспортируете функцию, а не объект:

module.exports  = function(data) // <---- this is a function
{
    var globs = {
        glob1 : data.toLowerCase(),
        glob2 : data.toUpperCase()
    }
    return globs;
}

и в app.js вы делаете это:

console.log(globs.glob1); <--- globs is a function, not an object

когда вы должны делать это:

console.log(globs().glob1);

Почему это?Хорошо, давайте на мгновение забудем ваш модуль.Рассмотрим следующий код:

var a = function(){ return 2 };

console.log(a);   // do you expect this to print a function or 2?
console.log(a()); // what do you expect this to print?

Это очень простое правило для функций во всех языках программирования, а не только в javascript: чтобы получить возвращаемое значение, необходимо вызвать функцию.Итак, в вашем коде:

function myExportedFunction (data) {
    // some logic here...
    return globs;
}

console.log(myExportedFunction);         // prints a function
console.log(myExportedFunction());       // prints the globs object
console.log(myExportedFunction().glob1); // prints value of glob1

Так что на самом деле все просто.Волшебный синтаксис не происходит.Вы просто забыли вернуть объект glob и вместо этого используете указатель на функцию.Очевидно, что функция не имеет свойства glob1, поэтому ее можно определить неопределенно.

Part2 - локальные переменные функции

OK.Допустим, вы внесли изменения, которые я рекомендовал выше.Существует очевидная проблема с тем, как была написана функция.Что происходит, когда вы делаете это:

var glob = require('glob.js')();
console.log(glob.glob1); // <--- prints "undefined"

Итак, первая проблема - вы не проверяете, передаете ли вы данные или ничего.Поэтому каждый раз, когда вы вызываете функцию, вы перезаписываете сохраненное значение.

Есть еще одна проблема: вы всегда возвращаете новый объект каждый раз, когда вызываете функцию.Давайте посмотрим, как работают локальные переменные при возврате:

function a () {
    var data = {}
    return data;
}

var x = a();
var y = a();

x.testing = 1;
y.testing = 2;

console.log(x.testing); // prints 1
console.log(y.testing); // prints 2

Итак, каждый раз, когда вы вызываете функцию, которая создает локальную переменную, вы возвращаете другой объект.На самом деле это не переменная, а буквальный синтаксис объекта:

var a = {};
// is basically the same as
var a = new Object();

Если мы изменим приведенный выше пример на:

function a () {
    return {};
}

, он все равно будет вести себя так же.

TLDR

Итак, как нам это исправить?Все просто, создайте объект вне функции и проверьте, передали ли мы data для инициализации:

var globs = {
    glob1 : "",
    glob2 : ""
}

module.exports  = function(data)
{
    globs.glob1 = data.toLowerCase();
    globs.glob2 = data.toUpperCase();

    return globs;
}

Теперь все должно работать:

В app.js

var global = require('glob.js')(data);

В mod.js

var global = require('glob.js')();

Эполог - модули - одиночные

Это может быть или не быть очевидным дляВы, почему выше должно работать.В случае, если вы уже знаете, почему я пишу это как ссылку для будущих читателей.

В файле node.js реализованы как правильные синглтоны.Поэтому в узле, если вам нужен синглтон, все, что вам нужно сделать, это написать модуль, вам не нужно реализовывать какой-либо специальный код для него.

Что это означает, что все глобальные переменные модуля (переменные области видимости модуля)распределяются между всеми требованиями.Вот очень простой модуль для совместного использования одной переменной среди всех модулей:

shared.js

var x = "";

module.exports = {
    set: function (val) {x=val},
    get: function () {return x}
}

a.js

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

shared.set("hello world");

b.js

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

console.log(shared.get()); // prints "hello world"

Мы используем эту функцию для объявления общей переменной glob в приведенном выше коде.

0 голосов
/ 21 октября 2018

Есть 2 варианта:

  1. Использовать переменную nodejs global (не рекомендуется)
  2. Создать общий модуль

Youвыбрал 2-й вариант, но сделал это немного неправильно, экспортировав функцию.Когда вы импортируете пакет и вызываете функцию, он всегда создает новый объект globs и выполняет его с вашими данными .Вместо этого вы можете экспортировать объект.Простой пример

glob.js
Здесь определен глобальный объект

module.exports = {
  glob1: '1',
  glob2: '2'
};

mod.js
Здесь вы можете изменить глобальный объект, например

var globs = require('./glob');

module.exports.updateGlob1 = function(data) {
  globs.glob1 = data;
};

app.js
Здесь, если вы обращаетесь к глобальной переменной, вымогу видеть его обновленным

var globs = require('./glob');
var mod = require('./mod');

mod.updateGlob1('1 plus 2');
console.log(globs.glob1); // Output: '1 plus 2'

Могут быть более сложные примеры, так как для шаблона проектирования модуля часто используется IIFE.

ОБНОВЛЕНИЕ

Другойпример использования IIFE.

glob.js

module.exports = (function() {
  var glob1 = 'initial value';

  return {
    // Getter method
    getGlob1() {
      return glob1;
    },

    // Setter method
    setGlob1(value) {
      glob1 = value;
    }
  }
})();

mod.js

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

module.exports.testFn = function() {
  // Access global variable with getter method
  console.log('In mod.js', shared.getGlob1());
};

app.js

var shared = require('./shared');
var mod = require('./mod');

// Print initial value
console.log('Initial', shared.getGlob1());

// Set new value to global variable
shared.setGlob1('new value');

// Print updated value
console.log('In app.js', shared.getGlob1());

// Use global variable in mod.js file
mod.testFn();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...