Хочу представить вашему вниманию boilerplate (skeleton) на базе React.js + Backbone для быстрого старта разработки приложения любой сложности. Эта связка помогла нашей команде в срок сделать сложное приложение с минимальным количеством проблем а простота позволила быстро подключать новых разработчиков в процесс.
Работая продолжительное время с JS, мы всякий раз сталкиваемся с разного рода проблемами и граблями. От череды неудач и разочарований мы создаем все новые и новые велосипеды, изобретаем фреймверки, пишем библиотеки, разрабатываем новые подходы. Я так же нахожусь в поисках Единорога и пытаюсь вывести для себя и своей команды нечто такое, что позволит нам сэкономить время на разработке и придать качество готовому продукту.
Начиная работу над одним из крупных проектов, встал вопрос о построении архитектуры и выборе фреймверка. Имея опыт с крупными проектами на Angular, Backbone, Ember и вспоминая их достоинства и недостатки, хотелось избавить нас от минусов и зачерпнуть все плюсы, а также освоить нечто новое. По этому выбор пал на тогда еще совсем свежий React, но возникла проблема с хранением данных в приложении и тут нам на помощь пришел Backbone. В общем, симбиоз из React + Backbone нам пришелся по душе, приложение ушло в продакшен, клиент доволен, а мы получили отличный инструмент для разработки, которым я бы хотел поделится с вами.
В чем его преимущество? Простота. Мы не изобретали нечто новое, это уже готовый, оттестированный, проверенный временем продукт. React дает нам отличный компонентный подход, с очень эффективным data-binding и отличным роутером. Backbone дает возможность создавать модели и коллекции. Синтаксис ES6, компилируемый gulp'ом через babel позволяет нам писать более компактный и приятный код, разбивать его на модули пригодные для тестирования и понимания.
В представляемом вам примере я написал небольшой TODO List с использованием Node.js + express.js + Mongo в качестве Restfull сервиса для манипуляций со списком работ. Исходники клиент приложения находятся в «client\source\»
Rocket React включает в себя:
Build system
Gulp — Настроенный сборщик, конфигурация находится в tasks/config.
NPM — Менеджер зависимостей. С его помощью происходит установка библиотек в приложение, с последующем их вызовом.
Browserify — DI менеджер.
Babel — поддержка ES6 синтаксиса.
babelify — Компиляция шаблонов React в JS.
Front End
React — Основа приложения. Страница и её элементы декомпозируются на малые компоненты, имеющие свою Backbone модель или коллекцию.
Backbone — Служит лишь для создания моделей и коллекций.
react.backbone — Модуль связывает React и Backbone.
wolfy87-eventemitter — Вынесен в Mixin для обмена сообщениями между компонентами. Пример можно посмотреть в «app\views\pubsub\».
react-router — роутинг.
Testing tool
Mocha, Chai, Sinon, jsdom — настроены и готовы к работе, поддерживают JSX синтаксис. Тесты находятся «tests\specs\».
Documentation
jsdoc — гнератор документации имеет баг, на сколько я понял, проблема в не полной поддержки JSDoc синтаксиса ES6, а именно, если в коде будет присутствовать arrow function, то компилятор не сбилдит документацию.
Server Side
Node, Express, Mongo, Mongoose, Winston — на основе этого стека технологий создано простое серверное приложение, для теста CRUD. находится в «server\».
Установка и запуск
1. Нужно запустить npm install в корне а также в папке server.
2. gulp b — производит билд клиентского приложения с sourcemaps.
3. gulp b --production собирает приложение вырезая консоль логи и дебаггеры и JS, минифицируя код.
4. gulp w — запуск watcher, livereload, и сервера с клиентской частью приложения.
5. gulp d — деплой приложения на FTP. перед деплоем проверяется валидность JS, если JS выдает ошибку, приложение не будет залито.
6. gulp doc — генерация документации через JSDoc, со своими настройками и кастомным шаблоном, поддержкой JSX. Смотрите настройки в jsdoc.conf.json.
7. gulp lint — производит проверку через JSHint. Файл с настройками в корне .jshintrc.
8. gulp test — запуск тестов из «tests\spec». Просмотреть результаты тестов можно из «show_test_results.html».
9. gulp test-w — запуск вотчера для тестов. Следит за папкой tests\spec и пере собирает если произошли изменения.
Основные настройки можно найти в файле «tasks/config.js».
mongo.bat — запускает Монго указывая путь к приложению.
copyright.txt — шаблон для копирайтов, будет встроен в собранный JS и CSS. Настройки находятся в «tasks/config.js».
Ссылка на Github
Комментарии (23)
matmuchrapna
07.08.2015 18:23+9и bat-файл, который не будет работать нигде кроме винды
AlexSergey
07.08.2015 22:55Этот файл особой роли не играет. Просто вложил его для удобства пользователей, которые будут работать из под Windows
Jabher
07.08.2015 18:36Оп, вовремя подвернулись под руку.
Как раз искал, кого бы помучать вопросом на эту тему: есть ли улучшения по перформансу при использовании react как шаблонизатора? По сравнению с классическими решениямиhell0w0rd
07.08.2015 22:17Почему вы рассматриваете реакт, как средство для увеличения производительности приложения? Если только для этого — есть более быстрые инструменты. React — это вовсе не про скорость, а про удобство написания и тестирования компонентов. Скорость — просто одно из достоинств реализации. Ну и ждите 0.14, там есть некоторые улучшения в этом плане.
Jabher
10.08.2015 16:51Я вообще на реакте с редуксом приложения пишу. Меня попросили проверить перформанс приложения на бэкбоне, я начал смотреть в сети сравнение движков рендеринга под бэкбон, не нашел толком ничего. Реакт как стандалон — куча бенчмарков. Реакт+бэкбон против чего-то еще — не найти ничего серьезного.
AlexSergey
07.08.2015 22:52Киллер фичей Реакта является скорость рендеринга, так как в Реакте используется виртуальный дом и мощный алгоритм сравнения измененных участков внутри компоненты, что позволяет обновлять только тот узел, где данные модели реально изменились. Есть куча сравнительных статей Реакта и прочих фреймверков, где подробно рассматриваются его преимущества в плане производительности. Лично я не проводил детальные исследования этого вопроса, как по мне, лучше не перегружать фронтэнд данными, не выводить в одну въюху коллекцию на тысячи элементов, это даже с точки зрения юзабилити будет не удобно и я уверен любой фреймверк с большим количеством данных будет тормозить.
hell0w0rd
08.08.2015 04:51и я уверен любой фреймверк с большим количеством данных будет тормозить
Слепая уверенность до добра не доводит: facebook.github.io/fixed-data-table/example-object-data.html
mr47
08.08.2015 07:34Можете смело найти не один десяток статей о том что «скорость» не одно из преимуществ React'а.
radist2s
07.08.2015 22:37На хабре ребята уже писали про облегченную версию Бэкбона "Exoskeleton". Там оставлена поддержка только для современных браузеров.
AlexSergey
07.08.2015 22:56Да, знаком с этой работой Паши Миллера. Хорошая вещь, но больше полу года не обновлялась. Бекбон относительно недавно обновился, может будет и дальше развиваться.
AlexSergey
07.08.2015 23:07Попросили сделать такой же скелетон, но с Ангуляром. Если кому то будет нужно, пользуйтесь на здоровье
Отличия — менеджер пакетов bower, убран browserify, sinon
Angular MEAN
ukko
07.08.2015 23:48+3Коллекции и модели от Backbone — это очень хорошо, но совершенно не про React. Мы у себя на проекте скрестили эти две технологии и теперь мучаемся. Лучше бы сразу на flux'е всё делали.
Проблема: Передаём в компонент коллекцию или только модель, меняем модель (коллекцию), сохраняем.
Ничего нигде не перерендеривается. React.state ничего не узнаёт о том что изменилась модель, потому что модель — это не плоская сущность.
Конечно можно использовать миксины вроде react-backbone, что проблему как бы решает, но в реальности только усугубляем положение, скрещивая две совершенно разных методики.
Вывод: Не используйте React и Backbone вместе, если вы вдруг решили это сделать прочитав статью. Поддержка этого решения дорого вам обойдётся.chegivara
08.08.2015 12:44Вот мой пример работы с React, Reflux и Backbone.
github.com/VladimirPal/react-flux-backbone
Проблемы описанной вами не наблюдается.
kSx
10.08.2015 06:29>> Поддержка этого решения дорого вам обойдётся.
Если не react-backbone, то можно обойтись добавлением чего-нибудь такого в компонент:
... = React.createClass({ ... componentDidMount: function() { this.props.model.on('change', function() { if (this.isMounted()) this.forceUpdate(); }.bind(this)); }, ... });
ukko
10.08.2015 09:18+1В любом случае — вам придётся скрещивать две разные методики и дублировать состояния в модели и в компоненте. Так же вам придётся отказаться от некоторых встроенных плюшек моделей и коллекций.
Я не говорю о том что невозможно скрестить эти две библиотеки, я говорю о том что чем больше проект, тем больше будет возникать проблем и сложностей с их поддержкой. И идея flux сразу писать кучу кода уже не выглядит настолько безумнойkSx
10.08.2015 16:03Понимаю, было бы здорово, если бы React изначально умел обращаться с Backbone. Мне всё же кажется, что это небольшая плата за совместимость двух полезных вещей, которые разрабатывались независимо. Такая прослойка при желании прячется и не фигурирует в основном коде.
Дублировать ничего не нужно, а события коллекций обрабатываются тем же образом.
Поделитесь, пожалуйста, опытом, если вы сталкивались с действительными проблемами такого подхода, которые усугубляют положение. Он будет полезен не только мне.
Поддерживаю перфекционизм, когда на него есть время. Но в данном случае это пока единственное, от чего пришлось отказаться.
ShpuntiK
12.08.2015 08:54Вы создали самый странный микс технологий для React из тех что я видел… React + Backbone + react-router + browserify…
Во-первых, если пишите Flux (а делать большое приложение на React и без Flux — странно), то модели и коллекции из Backbone — не лучшее решение. Когда хранилища являются простыми объектами — жить проще.
Во-вторых, если уж сильно так хочется backbone — хорошо, но зачем react-router? В backbone уже есть роутер. Только лишние зависимости тащите…
Ну в наконец — большинство ребят из коммьюнити React используют webpack (я говорю про тех, кто развивает React, кто выступает на конфах), а значит и большая масса пользователей тоже скорее всего на webpack сидит. Но ок, дело вкуса.
NeXTs_od
13.09.2015 12:51+1Добавил в закладки чтоб подсматривать гульп задачи по деплою на фтп и созданию док, спасибо)
Geba
Почему Backbone, а не Flux? Рассматривали ли Вы его?
AlexSergey
Рассматривал конечно. Flux как архитектура, в принципе может быть применима и в Rocket. В Rocket есть эмиттер, есть хранилища. При рассмотрении фреймверков на основе Flux лично мне не совсем понравилась громоздкость некоторых реализаций. А Бекбон сам по себе отличный фреймверк, с хорошими возможностями наследования, с кучей полезных методов, также как необходимая зависимость lodash в большинстве проектов будет полезна. Да и все это в совокупности весит немного, что тоже плюс.