Skip to content

Фреймворки в Node.js: Djangode

01/04/2010

Изображение: Node Garden

Djangode — фреймворк для Node.js, основанный на некоторых архитектурных решениях Django. Сейчас попробуем его в действии и сравним с Express.

Установка

К сожалению, на данный момент версия в kiwi не устанавливается, поэтому ставим через Git:

git clone git://github.com/simonw/djangode.git

С фреймворком сразу идут примеры, попробуем запустить один:

node example.js

Сервер запускается на 8009 порту (ну почему они все пытаются запуститься где попало?). К счастью, порт легко меняется на 8000 и я получаю доступ через nginx.

Демо-сайт радует страницей с дампом ошибок (да, ошибка в скрипте не убивает Node а показывается в виде аккуратной 500-ой страницы). Также есть демо редиректа и отдачи статического файла. В консоли при этом ведётся лог, правда не слишком подробный.

500 Error в Djangode

Также есть пример работы шаблонизатора:

node template_example.js

При запуске выдаётся предупреждение о том что process.mixin скоро будет удалён из ядра Node. При попытке открыть отрендерённый шаблон как HTML всё равно показывает исходник. Видимо заголовок Content-Type не приходит или приходит неправильный. Лезем в исходники — так оно и есть:

    ['^/text$', function (req, res) {
        template_loader.load_and_render('template.html', test_context, function (error, result) {
            if (error) {
                dj.default_show_500(req, res, error);
            } else {
                dj.respond(res, result, 'text/plain');
            }
        });
    }],

    ['^/html$', function (req, res) {
        template_loader.load_and_render('template.html', test_context, function (error, result) {
            if (error) {
                dj.default_show_500(req, res, error);
            } else {
                dj.respond(res, result, 'text/plain');
            }
        });
    }],

Т.е. это ошибка файла с примером, а не фреймворка. Это уже хорошо. Правим, перезапускаем, видим страницу.

Окей, посмотрим как под этим фреймворком пишется.

Использование

Это пример со страницы проекта:

var dj = require('./djangode');
    dj.serve(dj.makeApp([
        ['^/$', function(req, res) {
            dj.respond(res, '<h1>Homepage</h1>');
        }],
        ['^/other$', function(req, res) {
            dj.respond(res, '<h1>Other page</h1>');
        }],
        ['^/page/(\\d+)$', function(req, res, page) {
            dj.respond(res, '<h1>Page ' + page + '</h1>');
        }]
    ]), 8008); // Serves on port 8008

Первое что бросается в глаза — все пути задаются регулярными выражениями. Пока не знаю насколько это будет влиять на производительность, но думаю для большинства сайтов это вполне подходит. Пути в роутере задаются массивом, как в Nerve. В коллбек передаётся объект запроса — т.е. некоторые вещи с ним видимо всё таки приходится делать самостоятельно. Объект ответа также передаётся, и должен быть передан в dj.respond явно. В этом плане Express мне нравится больше — он абстрагирует нас от внутренних механизмов HTTPServer. Вероятность что нам придётся делать что то с этими объектами на самом деле минимальна.

Окей, что нам доступно ещё? Документация по Djangode к сожалению очень скудная, поэтому будем пользоваться лучшей документацией — исходным кодом 🙂

Оказывается, можно всё таки извлекать данные POST-запроса, просто этой функции надо явно передавать объект запроса (req). Шаблонизатор свой, на Mu похожий только синтаксисом, с неплохими возможностями — итераторы, дополнительные функции для обработки строк:

        <h1>Ordering notice</h1>

        {{ "test" }}

        <p>Dear {{person_name}},</p>

        <p>Thanks for placing an order from {{ company }}. It's scheduled to
        ship on {{ ship_date|date:"F j, Y" }}.</p>

        <p>Here are the items you've ordered:</p>

        <ul>
        {% for item in item_list %}
            <li>{{ forloop.revcounter0 }}: {{ item }} {{ forloop.counter|add:"1000" }}</li>
        {% endfor %}
        </ul>

        {% if ordered_warranty or true or false %}
            <p>Your warranty information will be included in the packaging.</p>
        {% else %}
            <p>You didn't order a warranty, so you're on your own when
            the products inevitably stop working.</p>
        {% endif %}

        {{ship.name}}{{ ship.nationality.toUpperCase }}

        <p>Sincerely,<br />{{ company }}</p>

Собственно, роутингом и темизацией возможности фреймворка и ограничиваются. В нём нет например работы с cookies или сессией. Возможность отдачи статических файлов — штука неплохая, Djangode даже сам может определять mime-тип отправляемого файла по расширению (поддерживается аж 165 расширений), но по хорошему такую задачу лучше передоверить nginx.

Что на самом деле хорошо — к фреймворку прилагается объёмная библиотека вспомогательных функций для работы с датой, строками и HTML-тегами. Примеры:

var strings = require('utils/string');
var html = require('utils/html');

var text = 'some people, when confronted with a problem, think "I know, I’ll use regular expressions." Now they have two problems.';

html.escape(text); // some people, when confronted with a problem, think &qout;I know, I’ll use regular expressions.&qout; Now they have two problems.

strings.smart_split(text); // Разбивает строку на слова, оставляя фразы в кавычках нетронутыми

strings.add_slashes(text); // some people, when confronted with a problem, think \"I know, I’ll use regular expressions.\" Now they have two problems.

strings.cap_first(text); // Some people, when confronted with a problem, think "I know, I’ll use regular expressions." Now they have two problems.

strings.sprintf('Some people, when confronted with a problem, think "%s" Now they have two problems.', 'I know, I’ll just use regular expressions.');

Все эти функции также можно использовать в шаблонах. Здесь приведена только малая часть функций. В общем, всё то что делает PHP (и видимо Django) таким удобным для простых задач обработки строк, но по умолчанию не входит в JavaScript. Помимо этого есть функции форматирования даты и времени (включая преобразование интервала в строку, например «2 days 4 hours»), различная обработка HTML и даже поддержка reduce для массивов. В функциях обработки дат есть поддержка локалей, позволяющая с небольшими усилиями выводить названия дней недели, месяцев и отрезков времени на нужном языке:

// Internationalization strings
var i18n = {
    'en-us': {
        days: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
               "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
        months: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
                 "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
        months_ap: ['Jan.', 'Feb.', 'March', 'April', 'May', 'June', 'July', 'Aug.', 'Sept.', 'Oct.', 'Nov.', 'Dec.'],
        ordinal_suffix: { 1: 'st', 2: 'nd', 3: 'rd', 21: 'st', 22: 'nd', 23: 'rd', 31: 'st', 'default': 'th' },
        special_times: ['midnight', 'noon'],
        timespan: ['year', 'years', 'month', 'months', 'week', 'weeks', 'day', 'days', 'hour', 'hours', 'minute', 'minutes']
    }
};

var cur_i18n = i18n['en-us'];

Заключение

По своему интересный фреймворк. В плюсах — неплохая библиотека вспомогательных функций, мощный шаблонизатор, удобная обработка ошибок прямо в браузере; в минусах — отсутствие документации, отсутствие какой-либо поддержки cookies и сессий, которые придётся реализовывать самостоятельно. Вердикт: фреймворк подойдёт для проекта где не нужно работать с сессиями, но надо работать с текстом. Но лучше всё таки взять что нибудь более документированное.

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

Фреймворки в Node.js

Ссылки по теме

Реклама
Добавить комментарий

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: