javascript - Dela variabler mellan filer i Node.js?
Här är 2 filer:
// main.js
require('./module');
console.log(name); // prints "foobar"
// module.js
name = "foobar";
När jag inte har "var" fungerar det. Men när jag har:
// module.js
var name = "foobar";
namn kommer att vara odefinierat i main.js.
Jag har hört att globala variabler är dåliga och att man bör använda "var" innan referenserna. Men är det här ett fall där globala variabler är bra?
Svar #1
Globala variabler är nästan aldrig en bra sak (kanske ett undantag eller två där ute...). I det här fallet verkar det som att du verkligen bara vill exportera din "name"-variabel. T.ex.,
// module.js
var name = "foobar";
// export it
exports.name = name;
Sedan, i main.js...
//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;
Svar #2
Jag kan inte hitta ett scenario där en global var är det bästa alternativet, självklart kan du ha en, men titta på dessa exempel och du kanske hittar ett bättre sätt att uppnå samma sak:
Scenario 1: Lägg sakerna i konfigurationsfiler
Du behöver ett värde som är detsamma i hela applikationen, men som ändras beroende på miljön (produktion, utveckling eller test), exempelvis e-posttypen, du skulle behöva:
// File: config/environments/production.json
{
"mailerType": "SMTP",
"mailerConfig": {
"service": "Gmail",
....
}
och
// File: config/environments/test.json
{
"mailerType": "Stub",
"mailerConfig": {
"error": false
}
}
(skapa en liknande konfiguration för dev också)
För att bestämma vilken konfiguration som kommer att laddas, skapa en huvudkonfigurationsfil (denna kommer att användas över hela applikationen)
// File: config/config.js
var _ = require('underscore');
module.exports = _.extend(
require(__dirname + '/../config/environments/' + process.env.NODE_ENV + '.json') || {});
Och nu kan du få datan på det här sättet:
// File: server.js
...
var config = require('./config/config');
...
mailer.setTransport(nodemailer.createTransport(config.mailerType, config.mailerConfig));
Scenario 2: Använd en konstantfil
// File: constants.js
module.exports = {
appName: 'My neat app',
currentAPIVersion: 3
};
Och använd det på det här sättet
// 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);
...
Scenario 3: Använd en hjälpfunktion för att hämta/ange data
Inte ett stort fan av den här, men åtminstone kan du spåra användningen av 'name' (med hänvisning till OP:s exempel) och införa valideringar.
// 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;
};
Och använd det
// 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();
...
Det kan finnas ett användningsfall när det inte finns någon annan lösning än att ha en global var, men vanligtvis kan du dela data i din app med hjälp av ett av dessa scenarier. Om du börjar använda node.js (som jag gjorde för ett tag sedan) försök att organisera sättet du hanterar data där eftersom det kan bli rörigt väldigt snabbt.
Svar #3
Om vi behöver dela flera variabler, använd följande format
//module.js
let name='foobar';
let city='xyz';
let company='companyName';
module.exports={
name,
city,
company
}
Användning
// main.js
require('./modules');
console.log(name); // print 'foobar'
