im simple message default title
PostgreSQL coub css express.js freeware git jquery laravel links linux macos mysql node.js php python task1 ubuntu vim virtualbox анекдот игры интересно музыка стихи цитаты

В 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 node.js

Наверное не нужно объяснять зачем это нужно.

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!
express.js node.js

Маленькие "хитрости" bash. На примере перезапуска приложения node.js
#!/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-файл чтобы потом что-то с этим процессом делать. Баш вообще интересная штука, жаль почти не остается времени на глубокие раскопки в этих шаманствах.
linux ubuntu node.js

Express.js error handing March 22, 2013
Поднобные объяснения на английском можно почитать вот тут. Суть в том, что в express.js метод передачи ошибок несколько отличается. Лично мне пока не очень понятно почему так, но инженер который собственно и разрабатывает express.js выбрал такой путь. Наверное с точки зрения идеологии node.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);
      }

      // тут что-то дальше происходит
      // ...
  });
};
express.js node.js

dbConfig.js
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()
mysql express.js node.js

HO-HO-HO!! L10 is here.
dance-dance #3
update new 01.10.2023