- PVSM.RU - https://www.pvsm.ru -
Доброго времени суток, уважаемые читатели Хабра. Всем давно известно, что во вселенной node.js существует привеликое множество фреймворков на любой вкус и цвет. Каждый из них удовлетворяет своим потребностям и содержит разнообразный набор возможностей и собственную архитектуру и иногда, чтобы сделать выбор, требуется взглянуть каждому из этих «зверей» под капот и провести аналитику. В моем случае требовался фреймворк уже более менее обладающий собственной архитектуройд; выбор происходил между 4 инструментами: kraken.js [1], sails.js [2], meteor.js [3] и derby.js [4]. Чтобы узнать о том, как это было, прошу под кат.
Эти два фреймворка уже подвергались сравнению [5] и я решил объединить их в одну секцию. Перечислю лишь те качества, которые показались для меня решающими при отказе от данных фреймворков:
Возможно поотдельности, те или иные компоненты я бы и использовал, но в целом инструменты, как бы их не хвалили и не пиарили, мне показались весьма специфичным и совершенно не упращающими жизнь разработчиков.
Kraken.js — это MVC фреймворк, выпущенный компанией PayPal относительно недавно, распространяемый как модуль npm, с основным акцентом на безопасности и поддержке интернационализации в приложении.
Помимо ядра в состав фреймворка входят еще четыре модуля:
Эти модули являются независмыми друг от друга (за исключением makara, который опирается на функционал adaro) и могут быть подключены и использованы в любом node.js приложении.
Своей структурой приложение очень сильно напоминает структуру любого MVC-приложения, с хранением файлов по их функицональному назначению:
/config - конфигурационные файлы
/controllers - контроллеры
/locales - .property-файлы локализации
/lib - общие библиотеки используемые по всему приложению (не понятно зачем, ведь все это можно хранить в npm модулях)
/models - модели данных
/public - web-ресурсы доступные публично
/public/templates - клиентские и браузерные шаблоны
/tasks - разбитые по файлам grunt-задачи автоматически регистрируемые с применением плагина grunt-config-dir
/tests - юнит и функцональные тесты
index.js - главный файл приложения
В то время когда в node.js есть CommonJS модули, с помощью которых мы можем реализовать динамическую конфигурацию приложения, kraken.js использует два .json-файла для development и production окружений, что существенно ограничивает наши возможности. Но, не смотря на данные ограничения, т.к. kraken.js базируется на уже набравшем популярность среди web-развработчиков фреймворке express.js [11], конфигурация его приложения может быть произведена любыми известными вами способами прямо в файле index.js или же с помощью самописного модуля конфигурирующего приложение. Кроме того, есть дополнительный модуль meddleware [12], существенно упрощающий конфигурацию middleware's [13] в вашем приложении.
Тут можно сказать, что он как бы есть, и в то же время его и нет. Весь роутинг выполняется вручную в файле контроллера, главной функции которого, предоставляется доступ к объекту router, и выглядит это следующим образом:
module.exports = function (router) {
var model = new IndexModel();
router.get('/', function (req, res) {
res.render('index', model);
});
};
Это конечно предоставляет больше гибкости при конфигурации, но вам не кажется что фреймворк, это в первую очередь инструмент, который призван уменьшать количество ручных действий прилагаемых программистом (сейчас в меня наверное полетят тухлые помидоры, но в целом так оно и есть). Когда ваше приложение разрастется до приемлемых размером, управление путями с таким роутингом станет делом не особо то и приятным…
Здесь создатели фреймворка решили предоставить разработчику полуную свободу выбора, дело в том, что модели в kraken.js являются обычными JavaScript-объектами со своими свойствами. Так что, выбираем любую понравившуюся вам ORM, устанавливаем ее через npm и вперед!
Тут не к чему придраться. Шаблонизатор поддерживает фильтры, блоки-секций, условные конструкции, в общем обеспечивает разработчика всем необходимым инструментарием и даже позводяет компилировать шаблоны для использования их на клиенте.
Поддержка переводов присутствует только в шаблонах, что существенно ограничивает наши возможности на сервере, ведь мы не можем просто взять и передать динамически собранную строку перевода в переменной шаблона. Кроме того, модуль выполняющий сам перевод, опирается на использование .property-файлов, сама организация которых не внушает особого доверия:
index.greeting=Hello {name}!
index.bye=Bye {name}!
Возможно в случае с простыми предложениями это еще хоть как-то сработает, но представьте, что будет в случае со сложными предложениями…
Sails.js был спроектирован и разработан Майком МакНилом [14] для создания масштабируемых приложений реального времени.
Sails.js состоит из ядра, которое построено из npm-модулей созданных и поддерживаемых другими разработичками, но и среди них имеется один очень интересный модуль — это ORM waterline [15], которая может выполнять миграции баз данных в полу-автоматическом режиме, и написанная специально для sails, и с легкостью подключаемая к любому node.js приложению. Кроме того, в ядро встроена поддержка генерации кода, которая может быть использована прямо из коммандной строки [16]. Кроме того имеется встроенная поддержка websocket's, позволяющая обрабатывать запрос поступивший через socket, как обычный запрос.
Структура очень похожа на MVC приложение, с более детальным дроблением по функциональным возможностям.
api/
controllers/ - контроллеры
models/ - модели
policies/ - политики управления доступом к методам контроллеров
...
services/ - singleton-сервисы используемые по всему приложению
assets/ - файлы которые будут в дальнейшем помещены в public директорию сайта
config/ - файлы конфигурации
tasks/
config/ - grunt-задачи
register/ - регистраторы grunt-задач
...
views/ - шаблоны
Gruntfile.js - файл для регистрации и запуска grunt-задач из окна терминала
app.js - главный файл приложения
.sailsrc - главный файл конфигурации приложения
Подробнее о назначении каждого файла, можно узнать из документации [17], которая позволяет одним нажатием на директорию или файл узнать его назначении.
Sails.js тоже основан на базе express.js, но в отличие от kraken.js он не предоставляет разработчику прямого доступа к объекту приложения и вся конфигурация выполняется посредством .js-файлов, которые представляют из себя CommonJS модули экспортирующие объекты отвечающие за настройку одного из компонентов ядра. Этот механизм позволяет отделить друг от друга настройку баз данных от найстройки HTTP-сервера, но очень сильно ограничивает возможности по конфигурации специфичных свойств приложения, например у меня вызвало сложность поменять путь по-умолчанию откуда будет происходить рендеринг шаблонов. Если же дело касается middleware, то вы можете его слегкостью подключить расположив его в секции middleware файла config/http.js.
Тут не к чему придраться. Роутинг настраивается путем указания нужного пути в файле config/routes.js в соответствующей секции и выглядит следующим образом:
module.exports = {
'get /signup': { view: 'conversion/signup' },
'post /signup': 'AuthController.processSignup',
'get /login': { view: 'portal/login' },
'post /login': 'AuthController.processLogin',
'/logout': 'AuthController.logout',
'get /me': 'UserController.profile'
}
Данный механизм является очень удобным, и позволяет настраивать выполять настройки без указания HTTP-метода, выполнять отображения шаблона без применения контроллера, указывать данные которые будут переданы в шаблон, политики доступа, которые необходимо проверить прежде чем предоставить пользователю доступ к определенному методу контроллера.
Как уже было сказано выше, в состав sails.js входит очень мощная ORM, которая основана на использовании адаптеров в различным источникам данных, которые существуют для множества известных баз данных. Модель представляется в виде CommonJS модуля экспортирующего свойства модели, которыми в дальнейшем будет расширен базовый класс коллекции Waterline.Collection. В ORM встроена поддержка нескольких дополнительных типов полей, которые применяют специфические валидаторы на протяжении всего жизненного цикла модели (подробнее читайте в документации), а так же возможность указывать для каждой модели определенное соединение с базой данных, которое будет использовано при записи и чтении данных модели. Кроме всего этого, есть встроенная поддержка пагинации, сортировок и обработчиков событий.
Типичный пример файла модели:
module.exports = {
connection: 'disk',
attributes: {
firstName: {
type: 'string',
required: true
},
lastName: {
type: 'string',
required: true,
}
}
});
Когда в структуре модели происходят изменения ORM автоматически определяет их при запуске и в случае, если автоматическое разрешение конфликтов не может быть произведено, ведет диалог с разработчиком.
Sails.js имеет поддержку большинства известных шаблонизаторов за встраивания применения библиотеки consolidate.js [18] от автора фреймворка express.js, что несомненно упрощает применение шаблонов в приложении. Просто выбираешь, и используешь!
Поддержка переводов присутствует в sails.js на протяжении всего жизненного цикла приложения, будь то серверный код, шаблон или .js-файл, ведь внутри sails.js использует библиотеку i18n [19]. Сами же переводы складываются в .json-файлы, и могут быть дополнены автоматически при попытке перевода текста, которого еще нет в файле. С одной стороны автоматическое наполнение создает проблемы по своевременному переводу, но всегда можно создать grunt-задачу, которая просканирует содержимое нужных файлов и соберет весь текст для переводов.
Подводя итог, я уме у меня сформировалась следующая таблица классификации, по пятибальной системе.
| Конфгурация | Роутинг | Модели | Шаблоны | Интернационализация | |
|---|---|---|---|---|---|
| Meteor.js | 3 | 5 | 4 | 4 | 2 |
| Derby.js | - | - | - | - | - |
| Kraken.js | 5 | 2 | 5 | 4 | 3 |
| Sails.js | 4 | 5 | 4 | 5 | 4 |
Не трудно догадаться, что мой выбор пал на sails.js, потому что мне более близка по духу структура проекта используемая фреймворком, и те возможности, которые он предоставляет «из коробки». Конечно же он имеет минусы касающиеся конфигурации и интернационализации, но это те минусы, с которыми в моем случае можно смириться или же реализовать, если мыслить согласно концепции фреймворка. Этой статьей, я ни в коем случае не склоняю вас в сторону того или иного инструмента, выбирайте сами, что вам близко по духу, и да прибудет с вами сила!
Автор: seth2810
Источник [20]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/69859
Ссылки в тексте:
[1] kraken.js: http://krakenjs.com/
[2] sails.js: http://sailsjs.org/
[3] meteor.js: https://www.meteor.com/
[4] derby.js: http://derbyjs.com/
[5] сравнению: http://habrahabr.ru/post/191664/
[6] Lusca: https://github.com/krakenjs/lusca
[7] Kappa: https://github.com/krakenjs/kappa
[8] Adaro: https://github.com/krakenjs/adaro
[9] dust.js: http://linkedin.github.io/dustjs/
[10] Makara: https://github.com/krakenjs/makara
[11] express.js: http://expressjs.com/
[12] meddleware: https://github.com/krakenjs/meddleware
[13] middleware's: http://expressjs.com/4x/api.html#middleware.api
[14] Майком МакНилом: http://michaelmcneil.com/
[15] waterline: https://github.com/balderdashy/waterline
[16] коммандной строки: http://sailsjs.org/#/documentation/reference/cli
[17] документации: http://sailsjs.org/#/documentation/anatomy/myApp
[18] consolidate.js: https://github.com/visionmedia/consolidate.js/
[19] i18n: https://github.com/mashpie/i18n-node
[20] Источник: http://habrahabr.ru/post/237287/
Нажмите здесь для печати.