PostgreSQL
coub
css
express.js
freeware
git
jquery
laravel
links
linux
macos
mysql
node.js
php
python
task1
ubuntu
vim
virtualbox
анекдот
игры
интересно
музыка
стихи
цитаты
express.js
node.js
express.js
node.js
linux
ubuntu
node.js
express.js
node.js
mysql
express.js
node.js
Express.js: листинг файлов папки/директории
May 03, 2013
В Api.Reference есть пример который показывает как разрешить листать все директории внутри public.
app.use(express.directory('public')) app.use(express.static('public'))Чтобы лучше понять как это работает можно посмотреть исходник
node_modules/express/node_modules/connect/lib/middleware/directory.jsВозникает вопрос, как быть если я не хочу разрешать листать весь public, а только конкретные папки? Решение может быть таким
// обычный static для public app.use(express.static(path.join(__dirname, 'public'))); // маунтим роут на папку которую будет обслуживать directory // + передаем опции отображения app.use('/files-list', express.static(path.join(__dirname, 'public', 'files'))); app.use('/files-list', express.directory(path.join(__dirname, 'public', 'files'), {hidden: true, icons: true}));Или в случае если имя папки на диске совпадает с роутом (тоже самое, только с реальным именем папки для правильных ссылок для загрузки файлов)
app.use('/files', express.directory(path.join(__dirname, 'public', 'files'), {icons: true}));Нашелся скринкаст на эту тему:
Express.js: .jade template to string
May 02, 2013
Наверное не нужно объяснять зачем это нужно.
test1.js
test1.jade
test1.js
exports.test1 = function(req, res){ res.render('test1', { title: 'test1' }, function(err, body) { console.log(body); }); res.send('wooo'); };
test1.jade
div = title p hello world!
Ubuntu: как получить PID запущенного процесса
March 26, 2013
Маленькие "хитрости" bash. На примере перезапуска приложения node.js
Из переменной (правильно называть это переменными??) $$ - можно получить PID текущего скрипта, то есть если вы планируете в нем зависнуть то имеет смысл положить куда-то PID-файл чтобы потом что-то с этим процессом делать. Баш вообще интересная штука, жаль почти не остается времени на глубокие раскопки в этих шаманствах.
#!/bin/bash # чтобы было легче жить, добавим все нужные пути в переменные DAEMON="/usr/local/bin/node" ROOT_DIR="/home/user/project-copy-folder" # тут на основании базовых путей выставляем пути к файлам PID, # логов и скрипта, запускающего само приложение PIDFILE="$ROOT_DIR/pidfile" SERVER="$ROOT_DIR/app.js" LOG_FILE="$ROOT_DIR/app.js.log" # останавливаемся, обратите внимание на то, как получается и обрабатывается PID echo -n "Stopping $SERVER: " kill -9 $(cat $PIDFILE) && echo 'ok stoped' || echo 'error on stop my-funny app' # чистим логи и убираем старый PID (это опционально) >$LOG_FILE >$PIDFILE # стартуем. тут самое как мне кажется, непонятное — это конструкция echo $! > $PIDFILE # здесь $! это PID последнего запущенного приложения (читаем ман по bash), с пониманием # этого нюанса становится понятно все остальное echo -n "Starting $SERVER: " `$DAEMON $SERVER > $LOG_FILE & echo $! > $PIDFILE &` && echo 'ok, started' || echo 'error on start my-funny app'Интересная особенность как мне показалось состоит в том, что если мы выполним например вот такой код
/usr/local/bin/node /home/user_name/project/app.js & echo $!То увидим напечатанный PID. А вот если исполнить тоже самое, но через eval
NODE='/usr/local/bin/node' APP='/home/user_name/project/app.js' `$NODE $APP &` echo $!То не увидим ничего. То есть eval где-то у себя это значение закусывает и нам оно нормально не доезжает. Соответственно решением (скорее всего одним из решений, так как я никакой не специалист по bash), будет получение PID-а прямо внутри этого самого eval-a как показано в первом примере.
Из переменной (правильно называть это переменными??) $$ - можно получить PID текущего скрипта, то есть если вы планируете в нем зависнуть то имеет смысл положить куда-то PID-файл чтобы потом что-то с этим процессом делать. Баш вообще интересная штука, жаль почти не остается времени на глубокие раскопки в этих шаманствах.
Express.js error handing
March 22, 2013
Поднобные объяснения на английском можно почитать вот тут.
Суть в том, что в express.js метод передачи ошибок несколько отличается. Лично мне пока не очень понятно почему так, но инженер который собственно и разрабатывает express.js выбрал такой путь. Наверное с точки зрения идеологии node.js и асинхронного программирования вообще - это правильно (именно передавать ошибки по цепочке, а не ловить их), но мне на данный момент кажется что это несколько кривовато. Если пойму со временем в чем смысл именно такого подхода, то допишу подробнее или исправлю запись.
Обычно в node.js exception-ы ловятся по-человечески, то есть вот так
Как управлять ошибками в express.js сейчас.
./app.js
Обычно в node.js exception-ы ловятся по-человечески, то есть вот так
app.get('/home', function(req, res){ // ошибка throw new Error('error text msg'); });В случае с express.js схема работы такая
app.get('/home', function(req, res, next){ // ошибка next(new Error('error text msg')); });Причем интересно, что в таком простом примере в express.js вполне сработает и первый вариант, но вот пример ниже уже работать не будет. Насколько я понял дело в том что выкинули общий хэндлер ошибок app.error(function(err,...)). Честно говоря причин такого решения я пока не нашел.
app.get('/home', function(req, res, next){ db.getRow("SELECT * FROM ...", function(err, row){ throw new Error('error text msg'); }); });В этом случае ошибка просвистит мимо и приложение завалится. Православный путь на данный момент — таскать все ошибки по цепочке вручную. Писанины к сожалению получается несколько больше, но вполне вписывается в предусмотренную схему. Неудобно, но пока найдется что-то повеселее - это рабочее решение. Надо будет собраться написать Tj на эту тему.
Как управлять ошибками в express.js сейчас.
./app.js
app.configure(function(){ //.. здесь вся остальная необходимая конфигурация // error 500 app.use(function(err, req, res, next) { res.status(500).render('err500', { title: 'ouch.. 500 error', err: err }); }); }); // "контроллер" блога var blog = require('./routes/blog'); // роут на конкретную операцию app.get('/post/:post_id', blog.blogPost);./routes/blog
// ... остальное содержимое контроллера exports.blogPost = function(req, res, next) { // .. проверки что-то ещё db.getRow("SEL33ECT b.* \ FROM blog b \ WHERE blog_id=?", [ post_id ], function(err, post){ // ловим ошибку if (err) { return next(err); } // тут что-то дальше происходит // ... }); };
Декоратор для mysql - node.js + express.js
December 25, 2012
dbConfig.js
Я вообще не уверен что это правильно полностью, надо бы узнать мнение корифеев (где б найти ещё их), но то что оно работает и это вообще возможно и не слишком замороченно - очень радует.
UPD: и правильно думал, ошибка здесь есть - см. Node.js + MySQL FOUND_ROWS()
module.exports = { user: 'root', password: 'root', host: '127.0.0.1', database: 'db' };db.js
/** * decorator for mysql */ var mysql = require('mysql'), dbConfig = require('./dbConfig'), conn = mysql.createConnection(dbConfig); // standard query exports.q = function(sql, callee, next){ if (typeof(callee) != 'object' || !(callee instanceof Array)) { calleeSend = []; } else { calleeSend = callee; } conn.query(sql, calleeSend, function(err, qres){ if (err){ if (typeof(callee) == 'function') { return callee(err); } else if (typeof(next) == 'function') { return next(err); } else { console.log('Uncaught DB error: ', err); console.log('Uncaught error in query: ', sql); } } try { if (typeof(callee) == 'function') { callee(err, qres); } else if (typeof(next) == 'function') { next(err, qres); } } catch(e) { next(e); } }); }; // get row exports.getRow = function(sql, callee, next){ if (typeof(callee) != 'object' || !(callee instanceof Array)) { calleeSend = []; } else { calleeSend = callee; } conn.query(sql, calleeSend, function(err, qres){ if (err){ if (typeof(callee) == 'function') { return callee(err); } else if (typeof(next) == 'function') { return next(err); } else { console.log('Uncaught DB error: ', err); console.log('Uncaught error in query: ', sql); } } row = (qres[0]) ? qres[0]: false ; try { if (typeof(callee) == 'function') { callee(err, row); } else if (typeof(next) == 'function') { next(err, row); } } catch(e) { next(e); } }); }; // last insert id exports.lastId = function(next){ conn.query("SELECT LAST_INSERT_ID() as id", function sres(err, qres){ var id = (qres[0].id) ? qres[0].id: false ; try { next(err, id); } catch (e) { return next(e); } }); }; // calc found rows exports.foundRows = function(next){ conn.query("select found_rows() as cnt", function(err, qres){ var cnt = (qres[0].cnt) ? qres[0].cnt : false ; try { next(err, cnt); } catch (e) { return next(e); } }); };Сам mysql — вот этот модуль npm install mysql
Я вообще не уверен что это правильно полностью, надо бы узнать мнение корифеев (где б найти ещё их), но то что оно работает и это вообще возможно и не слишком замороченно - очень радует.
UPD: и правильно думал, ошибка здесь есть - см. Node.js + MySQL FOUND_ROWS()