Как я уже писал, конкуренция среди облачных платформ привела к тому, что для для невысоких по нагрузке задач ими можно пользоваться абсолютно бесплатно. При этом каждая из платформ старается продвигать уникальные «фишки» и балансирует платные и бесплатные предложения, которые варьируются в очень широких пределах от многолетнего «Bizspark» у Azure до «засыпающих» на 8 часов в сутки инстансов Heroku. Недавно купленная facebook платформа «parse.com» предлагает собственный ORM, россыпь SDK для всех платформ и довольно интересный облачный хостинг «parse cloud code», позволяющий использовать в их облаке javascript не только для работы с данными, но и для создания средней сложности сайтов. Модель монетизации у них тоже любопытная: сервисом можно пользоваться бесплатно, пока количество запросов к одному приложению не превышает 30 в секунду. А это, между прочим, довольно много. Под катом я расскажу как в несколько строк кода сделать заготовку веб сервиса, используя самый актуальный стек технологий: typescript 1.6 с jsx, React 0.13 с es6, webpack с лоадерами в ассортименте и немного свежего express.js
Как уже знают многие читатели, я старательно и планомерно продвигаю на Хабре нашу платформу облачной телефонии voximplant, которая полностью управляема с помощью javascript и дружественна к веб разработчикам. К нам часто обращаются клиенты и партнеры, которые хотят из javascript во время звонков сохранять и читать данные: собирать статистику, рисовать dashboard, делать синхронизацию по внешним событиям и так далее. Мы им честно рассказываем что из нашего облака можно делать http запросы к любым сервисам, с помощью которых можно реализовать все что они хотят. И сталкиваемся с непониманием — «ну это же сервак поднимать надо… это сложно… долго… дорого». В этой статье я продемонстрирую насколько быстро сейчас можно собрать бесплатное fullstack решение, способное обрабатывать http запросы, хранить данные и быстро показывать их изменение. Ну а чтобы статья была интересна максимальному кругу хабражителей, сервис выбран необычный, а стек технологий — самый, не побоюсь этого слова, трендовый. Кстати, в комментариях приветствуются обсуждения js vs python vs ruby, react vs angular vs ember и webpack vs browserify vs grunt vs gulp.
Устанавливаем последнюю версию node.js, регистрируемся на parse и устанавливаем себе их одноименную command line tool по инструкции. Установленный toolchain даст нам волшебную команду parse, с помощью которой можно не только создать новый проект, но и загрузить его в облако, и посмотреть логи. В общем, все как у всех.
Приложение создается командой parse new, которая позволит создать новое приложение или подключиться к существующему, и в случае создания нового приложения — создаст минимальный «скелет» в указанной директории. Созданное приложение можно сразу же загрузить в облако, выполнив в его директории команду parse deploy. Отгруженное в облако приложение будет доступно по url, которое нужно задать в настройках веб интерфейса, раздел «hosting»:
Созданный скелет приложения состоит из двух файлов: cloud/main.js для javascript кода и public/index.html для статики. Если мы зайдем на заданный нами url, то увидим как раз содержимое статичного html файла:
Статика нам не очень интересна, поэтому запускаем команду parse generate, которая добавляет в наше приложение скелет express.js. Тут надо уточнить: в отличие от большинства других paas сервисов, parse.com это не node + git. Их облачная инфраструктура строится вокруг «голого» движка V8, в который они добавили модули стандарта common js и немного api. В их облако нельзя установить модули node.js (хотя можно «склеить» их в один .js файл вместе с приложением), а команда parse deploy никак не связана с git и просто копирует в облако содержимое директорий cloud и public, снабжая каждую загрузку «версией». После загрузки в облако всегда выполняется файл cloud/main.js в котором можно инициализировать express.js и получить полноценное приложение. Но постойте, откуда в облаке express.js, если там нет ноды? Все очень просто — parse предоставляет ряд популярных библиотек, которые можно загрузить с помощью require и использовать для создания приложений и доступа к сервисам. С полным списком можно ознакомиться здесь — он не то чтобы очень большой, но самое нужное там есть.
Если сейчас запустить модифицированное приложение, то мы снова увидим содержимое index.html. Причина в том, что генератор добавил файлы экспресс, но не прописал их в «точке входа» main.js. Исправляем это упущение и меняем содержимое main.js на такой код:
Обратите внимание, что при использовании поставляемых в комплекте библиотеки в require передается только имя библиотеки, а при загрузке ваших собственных файлов нужно прописывать путь от корня проекта. Такую реализацию require сделали ребята из parse, можно только догадываться зачем. В любом случае, загрузив новую версию приложения и перейдя по url /hello мы увидим работающий express.js
Typescript от Microsoft добавляет в javascript возможность использовать строгую типизацию (или не использовать, это дело добровольное), синтаксис es6 и много других интересных штук. Кроме модулей. То есть синтаксис для модулей в языке присутствует, но скомпилированные .ts файлы породят такое же количество .js файлов, в которых код работы с модулями превратиться в набор вызовов api по выбранному стандарту: common js, amd итд. Можно, конечно, собрать отдельно common js версию для backend, amd для frontend, подключить загрузчик amd… Но есть вариант проще: использовать один из инструментов управления зависимостями, который склеит все получившиеся .js файлы в один, правильно «пропатчив» код работы с модулями.
В качестве такой системы я выбрал webpack — самое последнее решение, способное при удачном стечении обстоятельств не только организовать модули, но и заменить систему сборки, в роли которой обычно выступает grunt или gulp
Для установки компилятора typescript, webpack и ряда полезных утилит используем следующее заклинание node package manager (который обычно ставится вместе с node.js):
Чтобы typescript хорошо работал и проверял типы, нужно установить так называемые «type definitions» — описания типов для популярных библиотек, которые создаются и поддерживаются разработчиками. Делается это с помощью утилиты tsd, которую мы поставили вместе с компилятором:
Чтобы webpack собирал typescript, создадим для него конфигурационный файл webpack.config.js, единственный объемный кусок кода в моей демонстрации:
Теперь можно стереть все из папок public и cloud, заменив на единственный файл с кратким кодом бэкенда, src/backend.ts:
Краткость — сестра. Собираем и отгружаем в облако:
ReactJS, детище Facebook, было создано с амбициозной целью починить чатик. И как-то неожиданно обрело мировую известность. Основной «фичей» стал не рекламируемый shadow dom с быстрыми обновлениями, а возможность раздробить интерфейс и часть логики веб приложения на небольшие, простые и хорошо изолированные кусочки. Добавляем в наш проект саму библиотеку, не забывая о type definitions для typescript:
Добавим в конфигурацию webpack правила для сборки frontend части:
И собственно сам код frontend в файле src/frontend.tsx, который так же будет написан на typescript (обратите внимание на расширение, гремучая смесь typescript и xml):
Чтобы React загрузился на фронтенде, немного модифицируем src/backend.ts:
Все готово — собираем, загружаем в облако и видим заготовку пользовательского интерфейса на ReactJS. Которую можно очень быстро превратить в полноценный интерфейс с помощью готовых наборов компонентов
Webpack — это не только конкурент Browserify, нехорошо поглядывающий на gulp. Это еще и возможность подключать через require файлы, отличные от javascript. Например — css стили. Или sass, что сейчас более популярно. У такого подхода есть плюсы и минусы, при этом плюсы лежат в области лучшей читаемости и организации кода, а минусы — в скорости загрузки того что получилось. Каждый выбирает под свои задачи, главное — чтобы было легко использовать. А с webpack подключение sass стилей становится вопросом одной строчки кода. Вот такой:
Благодаря настойкам в конфигурационном файле webpack, указанный .scss файл будет преобразован в css, добавлен в виде текстовой строки в результирующий javascript и автоматически загружен в dom на клиенте. При необходимости процесс можно тонко подстроить под свои нужды и оптимизировать по скорости загрузки, но простейший случай решается ровно в одну строчку кода, что не может не радовать. Загруженные стили можно использовать в ReactJS в соответствии с синтаксисом JSX:
Основная сила Parse лежит в ORM: возможность создавать объекты «на лету», складировать их в емкую базу данных и получать обратно простым javascript кодом позволяет создавать прототипы веб приложений с очень высокой скоростью. Я не стал добавлять в статью еще и пример работы с данными, чтобы не получить очередной wall of text, но документация на официальном сайте позволяет быстро войти в курс дела. А если добавить к этому ReactJS с готовыми компонентами для пользовательского интерфейса, встроенный в Parse механизм работы с пользователями и удобный набор «батареек», то получившийся комбайн в умелых руках способен на многое. Плюс к этому — бесплатный тарифный план, в который умещается очень много не только небольших, но и средних проектов. 30 запросов в секунду это много. И это я не говорю про мобильные SDK, React Native и встроенную в dashboard систему аналитики. Есть на что посмотреть.
К минусам следует отнести общую слабость хостинговой платформы: по моим ощущениям, все создавалось вокруг ORM, и возможности делать веб приложения и выполнять произвольный код в облаке были добавлены значительно позже. Голый V8 вместо node.js, невозможность установить большинство модулей и еще ряд ограничений не позволяют рассматривать parse как совсем универсальное решение. Но, тем не менее, для многих задач платформа подходит очень хорошо — что, я надеюсь, и было продемонстрировано в статье. Вопросы, уточнения, немного флейма в понедельник?
Зачем еще одна платформа
Как уже знают многие читатели, я старательно и планомерно продвигаю на Хабре нашу платформу облачной телефонии voximplant, которая полностью управляема с помощью javascript и дружественна к веб разработчикам. К нам часто обращаются клиенты и партнеры, которые хотят из javascript во время звонков сохранять и читать данные: собирать статистику, рисовать dashboard, делать синхронизацию по внешним событиям и так далее. Мы им честно рассказываем что из нашего облака можно делать http запросы к любым сервисам, с помощью которых можно реализовать все что они хотят. И сталкиваемся с непониманием — «ну это же сервак поднимать надо… это сложно… долго… дорого». В этой статье я продемонстрирую насколько быстро сейчас можно собрать бесплатное fullstack решение, способное обрабатывать http запросы, хранить данные и быстро показывать их изменение. Ну а чтобы статья была интересна максимальному кругу хабражителей, сервис выбран необычный, а стек технологий — самый, не побоюсь этого слова, трендовый. Кстати, в комментариях приветствуются обсуждения js vs python vs ruby, react vs angular vs ember и webpack vs browserify vs grunt vs gulp.
Подготавливаем toolchain
Устанавливаем последнюю версию node.js, регистрируемся на parse и устанавливаем себе их одноименную command line tool по инструкции. Установленный toolchain даст нам волшебную команду parse, с помощью которой можно не только создать новый проект, но и загрузить его в облако, и посмотреть логи. В общем, все как у всех.
Создаем приложение
Приложение создается командой parse new, которая позволит создать новое приложение или подключиться к существующему, и в случае создания нового приложения — создаст минимальный «скелет» в указанной директории. Созданное приложение можно сразу же загрузить в облако, выполнив в его директории команду parse deploy. Отгруженное в облако приложение будет доступно по url, которое нужно задать в настройках веб интерфейса, раздел «hosting»:
Созданный скелет приложения состоит из двух файлов: cloud/main.js для javascript кода и public/index.html для статики. Если мы зайдем на заданный нами url, то увидим как раз содержимое статичного html файла:
Добавляем немного express.js
Статика нам не очень интересна, поэтому запускаем команду parse generate, которая добавляет в наше приложение скелет express.js. Тут надо уточнить: в отличие от большинства других paas сервисов, parse.com это не node + git. Их облачная инфраструктура строится вокруг «голого» движка V8, в который они добавили модули стандарта common js и немного api. В их облако нельзя установить модули node.js (хотя можно «склеить» их в один .js файл вместе с приложением), а команда parse deploy никак не связана с git и просто копирует в облако содержимое директорий cloud и public, снабжая каждую загрузку «версией». После загрузки в облако всегда выполняется файл cloud/main.js в котором можно инициализировать express.js и получить полноценное приложение. Но постойте, откуда в облаке express.js, если там нет ноды? Все очень просто — parse предоставляет ряд популярных библиотек, которые можно загрузить с помощью require и использовать для создания приложений и доступа к сервисам. С полным списком можно ознакомиться здесь — он не то чтобы очень большой, но самое нужное там есть.
Если сейчас запустить модифицированное приложение, то мы снова увидим содержимое index.html. Причина в том, что генератор добавил файлы экспресс, но не прописал их в «точке входа» main.js. Исправляем это упущение и меняем содержимое main.js на такой код:
require('cloud/app.js');
Обратите внимание, что при использовании поставляемых в комплекте библиотеки в require передается только имя библиотеки, а при загрузке ваших собственных файлов нужно прописывать путь от корня проекта. Такую реализацию require сделали ребята из parse, можно только догадываться зачем. В любом случае, загрузив новую версию приложения и перейдя по url /hello мы увидим работающий express.js
Переходим на typescript
Typescript от Microsoft добавляет в javascript возможность использовать строгую типизацию (или не использовать, это дело добровольное), синтаксис es6 и много других интересных штук. Кроме модулей. То есть синтаксис для модулей в языке присутствует, но скомпилированные .ts файлы породят такое же количество .js файлов, в которых код работы с модулями превратиться в набор вызовов api по выбранному стандарту: common js, amd итд. Можно, конечно, собрать отдельно common js версию для backend, amd для frontend, подключить загрузчик amd… Но есть вариант проще: использовать один из инструментов управления зависимостями, который склеит все получившиеся .js файлы в один, правильно «пропатчив» код работы с модулями.
В качестве такой системы я выбрал webpack — самое последнее решение, способное при удачном стечении обстоятельств не только организовать модули, но и заменить систему сборки, в роли которой обычно выступает grunt или gulp
Для установки компилятора typescript, webpack и ряда полезных утилит используем следующее заклинание node package manager (который обычно ставится вместе с node.js):
npm init
npm install typescript tsd webpack underscore ts-loader style-loader css-loader sass-loader node-sass --save
Чтобы typescript хорошо работал и проверял типы, нужно установить так называемые «type definitions» — описания типов для популярных библиотек, которые создаются и поддерживаются разработчиками. Делается это с помощью утилиты tsd, которую мы поставили вместе с компилятором:
tsd install express
tsd rebundle
Чтобы webpack собирал typescript, создадим для него конфигурационный файл webpack.config.js, единственный объемный кусок кода в моей демонстрации:
var _ = require('underscore');
var BASE_CFG = {
resolve: {
extensions: ['', '.js', '.ts', '.jsx', '.tsx'],
},
module: {
loaders: [
{test: /\.ts(x?)$/, loader: 'ts-loader'},
{test: /\.scss$/, loaders: ['style', 'css', 'sass']},
],
},
};
var BACKEND_CFG = _.extend({}, BASE_CFG, {
target: 'node',
entry: './src/backend.ts',
output: {
path: './cloud',
filename: 'main.js',
},
externals: {
'express': 'commonjs express',
},
});
module.exports = [BACKEND_CFG];
Теперь можно стереть все из папок public и cloud, заменив на единственный файл с кратким кодом бэкенда, src/backend.ts:
/// <reference path="../typings/tsd.d.ts" />
import * as express from 'express';
const app = express();
app.get('/', (req, res) => res.end("hello, habr!"));
app.listen(8080);
Краткость — сестра. Собираем и отгружаем в облако:
webpack
parse deploy
Добавляем ReactJS
ReactJS, детище Facebook, было создано с амбициозной целью починить чатик. И как-то неожиданно обрело мировую известность. Основной «фичей» стал не рекламируемый shadow dom с быстрыми обновлениями, а возможность раздробить интерфейс и часть логики веб приложения на небольшие, простые и хорошо изолированные кусочки. Добавляем в наш проект саму библиотеку, не забывая о type definitions для typescript:
npm install react --save
tsd install react --save
Добавим в конфигурацию webpack правила для сборки frontend части:
var FRONTEND_CFG = _.extend({}, BASE_CFG, {
target: 'web',
entry: './src/frontend.tsx',
output: {
path: './public',
filename: 'frontend.js',
},
ts: {
compilerOptions: {
'jsx': 'react',
},
},
});
module.exports = [FRONTEND_CFG, BACKEND_CFG];
И собственно сам код frontend в файле src/frontend.tsx, который так же будет написан на typescript (обратите внимание на расширение, гремучая смесь typescript и xml):
/// <reference path="../typings/tsd.d.ts" />
import * as React from 'react';
class Ui extends React.Component<any, any> {
render() {
return <div>helo, habr</div>;
}
}
document.addEventListener('DOMContentLoaded', () => {
React.render(React.createElement(Ui), document.body);
});
Чтобы React загрузился на фронтенде, немного модифицируем src/backend.ts:
app.get('/', (req, res) => {
res.end('<script type="text/javascript" src="frontend.js"></script>');
});
Все готово — собираем, загружаем в облако и видим заготовку пользовательского интерфейса на ReactJS. Которую можно очень быстро превратить в полноценный интерфейс с помощью готовых наборов компонентов
Добавляем SASS
Webpack — это не только конкурент Browserify, нехорошо поглядывающий на gulp. Это еще и возможность подключать через require файлы, отличные от javascript. Например — css стили. Или sass, что сейчас более популярно. У такого подхода есть плюсы и минусы, при этом плюсы лежат в области лучшей читаемости и организации кода, а минусы — в скорости загрузки того что получилось. Каждый выбирает под свои задачи, главное — чтобы было легко использовать. А с webpack подключение sass стилей становится вопросом одной строчки кода. Вот такой:
require("./frontend.scss");
Благодаря настойкам в конфигурационном файле webpack, указанный .scss файл будет преобразован в css, добавлен в виде текстовой строки в результирующий javascript и автоматически загружен в dom на клиенте. При необходимости процесс можно тонко подстроить под свои нужды и оптимизировать по скорости загрузки, но простейший случай решается ровно в одну строчку кода, что не может не радовать. Загруженные стили можно использовать в ReactJS в соответствии с синтаксисом JSX:
render() {
return <div className='ui'>styled hello, habr</div>
}
Заключение
Основная сила Parse лежит в ORM: возможность создавать объекты «на лету», складировать их в емкую базу данных и получать обратно простым javascript кодом позволяет создавать прототипы веб приложений с очень высокой скоростью. Я не стал добавлять в статью еще и пример работы с данными, чтобы не получить очередной wall of text, но документация на официальном сайте позволяет быстро войти в курс дела. А если добавить к этому ReactJS с готовыми компонентами для пользовательского интерфейса, встроенный в Parse механизм работы с пользователями и удобный набор «батареек», то получившийся комбайн в умелых руках способен на многое. Плюс к этому — бесплатный тарифный план, в который умещается очень много не только небольших, но и средних проектов. 30 запросов в секунду это много. И это я не говорю про мобильные SDK, React Native и встроенную в dashboard систему аналитики. Есть на что посмотреть.
К минусам следует отнести общую слабость хостинговой платформы: по моим ощущениям, все создавалось вокруг ORM, и возможности делать веб приложения и выполнять произвольный код в облаке были добавлены значительно позже. Голый V8 вместо node.js, невозможность установить большинство модулей и еще ряд ограничений не позволяют рассматривать parse как совсем универсальное решение. Но, тем не менее, для многих задач платформа подходит очень хорошо — что, я надеюсь, и было продемонстрировано в статье. Вопросы, уточнения, немного флейма в понедельник?
Комментарии (8)
Anisotropic
05.10.2015 11:32>react vs angular vs amber
Amber.js переименовали в Ember.js 4 года назад :)eyeofhell
05.10.2015 12:10+1Точно, это уже не первый раз когда я так опечатываюсь -_-. Хорошо хоть Qt пока правильно пишу :).
aylarov
05.10.2015 13:39+1TypeScript + React + Webpack отличное сочетание, еще бы в Sublime нормально работал плагин для TypeScript (подгружал type definitions без проблем)…
forcewake
05.10.2015 18:44+1Можете попробовать Atom с пакетом atom-typescript. Даже сейчас вполне юзабельно и вполне себе удобно использовать.
RUQ
Стоит сказать, что основной для javascript'ового API Parse служит Backbone. Но если хотите использовать его на 100%, то всё же необходимо подключить его отдельно (backbone). А в целом Parse очень крутое подспорье frontend-специалисту, помогает на ранних стадиях приложения обходится вообще без backend-части, соответственно экономятся силы и время.
В Parse есть всё для построения стандартных CRUD систем, кроме того есть api для работы с гео-объектами, файлами, упрощённая регистрация пользователей + facebook login.
eyeofhell
Плюсую, backbone там есть. Правда, не в чистом виде, а в виде форка, на котором построен их SDK для работы с ORM. Сделать require('backbone') в cloud code нельзя :)
kurtov
В недавней версии 1.6 решили отказаться от использование Backbone и развиваться своим путем.
«SDK no longer contains Backbone-specific behavior. Moving forward, the core SDK will not be tied to any single framework, but we will work with the community to produce up-to-date bindings like Parse+React. The major changes are the removal of Parse.Collection, and allowing Parse.Objects to act as event channels.»