#javascript #node.js
#javascript #node.js
Вопрос:
У меня есть простое приложение с двумя пользовательскими модулями
app.js:
var mappings = require('./mappings.js');
var actions = require('./actions.js');
http.createServer(function (req, res) {
var alias = req.url.substring(1);
console.log(req.url);
console.log(alias);
var mapping = mappings[alias] || {
action: 'error',
statusCode: 404,
data: 'File not found'
};
actions[mapping.action](res,mapping);
}).listen(3000);
mappings.js:
var mappings = {
'goloroden': {
action: 'redirect',
url: 'http://www.goloroden.de',
type: 'permanent'
},
'polarbear': {
action: 'download',
url: 'http://www.goloroden.de/images/Logo.png',
fileName: 'PolarBear.png',
contentType: 'image/png',
forceDownload: false
},
'portrait': {
action: 'download',
url: 'file://./DSC_1067-2.jpg',
contentType: 'image/jpeg',
forceDownload: false
}
};
module.exports = mappings;
actions.js:
var http = require('http');
var fs = require('fs');
var url = require('url');
var deliverDownload = function (res, mapping, data) {
var contentDisposition =
mapping.forceDownload ? 'attachement' : 'inline';
res.writeHead(data.statusCode, {
'Content-Type': mapping.contentType,
'Content-Disposition': contentDisposition '; filename=' mapping.fileName ';'
});
data.pipe(res);
};
var actions = {
'download': function (res, mapping) {
var options = url.parse(mapping.url);
switch(options.protocol) {
case 'http:':
http.get(url.parse(mapping.url), function (data) {
deliverDownload(res, mapping, data);
});
break;
case 'file:':
var data = fs.createReadStream(options.host options.path);
data.statusCode = 200;
deliverDownload(res, mapping, data);
break;
}
},
'error': function (res, mapping) {
res.writeHead(mapping.statusCode, {
'Content-Type': 'text/html'
});
res.end(mapping.statusCode ' ' mapping.data);
},
'redirect': function (res, mapping) {
var statusCode = mapping.type === 'permanent' ? 301 : 307;
res.writeHead(statusCode, {
'Location': mapping.url
});
res.end();
}
};
module.exports = actions;
Поэтому, когда я пытаюсь запустить этот пример, я получаю эту ошибку: ReferenceError: http не определен.
Но я не могу понять, почему. http требуется в actions.js
Должен ли я вызывать его в app.js слишком? если да, то почему?
Ответ №1:
Вам придется, потому что вы не экспортировали http-модуль в свой actions.js
.
Вы экспортировали actions
, что:
var actions = {
'download': function (res, mapping) {
var options = url.parse(mapping.url);
switch(options.protocol) {
case 'http:':
http.get(url.parse(mapping.url), function (data) {
deliverDownload(res, mapping, data);
});
break;
case 'file:':
var data = fs.createReadStream(options.host options.path);
data.statusCode = 200;
deliverDownload(res, mapping, data);
break;
}
},
'error': function (res, mapping) {
res.writeHead(mapping.statusCode, {
'Content-Type': 'text/html'
});
res.end(mapping.statusCode ' ' mapping.data);
},
'redirect': function (res, mapping) {
var statusCode = mapping.type === 'permanent' ? 301 : 307;
res.writeHead(statusCode, {
'Location': mapping.url
});
res.end();
}
};
Когда вы говорите var someModule = require('someModule')
, что включаете все, что было экспортировано, someModule
когда это происходит module.exports = ...;
Итак, в app.js
ваших действиях var — это объект с download
функциями , error
, и redirect
.
Комментарии:
1. Итак, как это с другой стороны? http-модуль находится в app.js ; и actions.js требуется в app.js . Но когда я удаляю модуль из actions.js , это больше не сработает
2. @galileoGalilei Я смущен вашим вопросом. Я не уверен, в чем проблема. Вам обязательно следует ознакомиться с документацией , о которой говорил Итан Браун.
3. «Переменные, локальные для модуля, будут закрытыми, как если бы модуль был заключен в функцию».-> Это ответило на мой вопрос. Еще раз спасибо
4. @galileoGalilei Это правда, но вы также можете сделать их общедоступными, экспортировав их.
Ответ №2:
Да, вы делаете. Каждый модуль имеет свою собственную область видимости, и переменные, определенные в них, недоступны за пределами модуля, если вы не добавите его в module.exports
. Когда вы require
что-то делаете, вы просто создаете переменную, и на нее распространяются все обычные правила определения области видимости.
Если это сбивает с толку, вы можете прочитать документацию по модулю узла.