Pull to refresh

Meteor — Node.js для гуманитариев

Reading time 6 min
Views 58K

Введение


На хабре уже несколько раз упоминали о проекте Meteor, основанном в 2011 году семерыми энтузиастами web-технологий из Сан-Франциско. По сути Meteor является просто надстройкой над node.js, который сам ещё даже не дошёл до релизной версии. Тем не менее проект собрал более семи тысяч подписчиков на github и получил 11 миллионов долларов инвестиций.
С чего такая популярность? Дело в заявлении авторов о том, что они хотят кардинально переосмыслить способ написания современных web-приложений в сторону его упрощения. Не секрет, что написание кода на чистом node.js довольно сильно выворачивает мозг и вынуждает использовать различные костыли image в виде control flow средств. На Meteor, говорят авторы, писать крутые приложения сможет даже гуманитарий.
Ну что же, проверим. Имеется: 1 гуманитарий-социолог, закрывший сессию и желающий после Парсонса и Зиммеля перейти на что-нибудь полегче, компьютер с Ubuntu 12.10 и установленный node.js (не спрашивайте, как он оказался у социолога).

Вдохновимся обещаниями разработчиков, прекрасной девушкой-членом команды и начнём.

Установка


Установка элементарна – пишем в терминале
$ curl https://install.meteor.com | sh

Создание и запуск первого приложения


Для того, чтобы создать первое приложение, напишем в терминале
$ meteor create <имя_приложения>

Для запуска необходимо прописать слово meteor в директории приложения
$ cd <имя_приложения>
$ meteor

Заходим на http://localhost:3000/ и видим наш Hello world
Да, не врут ребята, ничего сложного, даже hello world за нас написали.

Простой блог


Но нам же надо что-нибудь позабористей. Напишем, например, простенький блог.
Disclaimer: вообще-то meteor (как и node.js) предназначен в первую очередь для создания сложных одностраничных приложений и в обычном блоге многие его возможности останутся неиспользованными.

Структура


Meteor исповедует идеологию «Один код на сервере и клиенте». Это выражается в том, что код из всех .js-файлов в проекте (.coffee также допустим при установке соответствующего smart package) за исключением такового в поддиректориях server, client и public исполняются как на серверной стороне в node.js (через fiber), так и в браузере у пользователя.
Код из директории server может исполняться только на сервере, из client — на клиентской, а в public, где хранятся статичные файлы, его вообще не должно быть. Также в нашем распоряжении имеются логические переменные Meteor.isClient и Meteor.isServer, которые принимают различные значения в зависимости от того, где исполняется код.
То же самое относится к .css и .html файлам — они могут быть разбросаны по всему проекту. Meteor сам найдёт и соберёт их вместе.
Есть ещё одна особая директория test, из которой ничто никуда по умолчанию не загружается.
Так же необходимо понять, что meteor – это такая сборная солянка из многих технологий, так что чистого javascript'а может быть совсем немного. jQuery и Underscore здесь правят балом. Не надо ничего устанавливать, просто пишите как вы привыкли. В качестве шаблонизатора используется Handlebars – продвинутая версия Mustache. Общение с базой данных MongoDB (обещается поддержка и других вариантов) осуществляется с помощью Minimongo (minimongo.com судя по всему обещает приятную работу с этой обёрткой).
В качестве css фреймворка в данном примере будет использован Foundation, который мне нравится больше аналогичного Twitter Bootstrap, но это дело вкуса.

Вывод записей


Начнём с обращения к базе данных. На сервере в .js файле создадим новую коллекцию, в которой будут храниться все наши записи.
Posts = new Meteor.Collection("posts");

Там же зададим начальные значения:
  Meteor.startup(function () { // этот код исполняется сразу после запуска
    if (Posts.find().count() === 0) {
      var posts = [
      {
        title: "Title one",
        text: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Et iure porro sunt repudiandae amet saepe asperiores commodi repellendus hic accusamus obcaecati ipsum modi magnam nulla magni vitae ea voluptates dignissimos!",
        published: (new Date()).toLocaleTimeString()
      },
      {
        title: "Title two",
        text: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Culpa natus mollitia similique accusamus minus harum magnam eum pariatur rerum fugit ducimus sapiente asperiores quidem molestias repudiandae consequuntur repellendus dolorum placeat.",
        published: (new Date()).toLocaleTimeString()
      }
      ];
      for (var i = 0; i < posts.length; i++) {
        Posts.insert({
          title: posts[i].title,
          text: posts[i].text,
          published: posts[i].published,
        });
      }
    }
  });

Затем создадим Handlebars шаблон отображения записей и назовём его stream:
<head>
  <title>Blog</title>
</head>

<body>
  <div class="row">
    <div class="twelve columns">
      {{> stream}}
    </div>
  </div>
</body>

<template name="stream">
  {{#each posts}}
    {{> post}}
  {{/each}}
</template>

<template name="post">
  <div class="panel">
    <h2>{{title}}</h2>
    <p>{{{text}}}</p> <!-- Три фигурные скобки означают, что HTML разметка не будет экранироваться -->
    {{published}}
  </div>
</template>

… и выведем через него начальные значения.
  Template.stream.posts = function () {
    return Posts.find({}, {sort: {published: -1}});
  };

Таким образом мы вывели все записи на главную страницу.

Добавление и удаление записей


Для того, чтобы добавить свои записи сначала создадим новый шаблон editor с соответствующей формой добавления:
<template name="editor">
  <h1>Новая запись</h1>
  <label>Заголовок
    <br>
    <input type="text" id="title-area" placeholder="">
  </label>
  <label>Текст
    <br>
    <textarea type="text" id="editor-area" placeholder=""></textarea>
  </label>
  <button id="submit-post" class="button radius">Опубликовать</button>
</template>

Следующий шаг — создание обработчика события, который при клике на кнопку будет добавлять содержимое полей в базу данных. Добавленная информация будет сразу же выводиться на все клиенты.
  Template.editor.events({
    "click #submit-post": function() {
      var published_date = new Date();
      Posts.insert({
        title: document.getElementById("title-area").value,
        text: document.getElementById("editor-area").value,
        published: published_date.toLocaleTimeString()
      })      
    }    
  });

Чтобы удалить ненужные записи из базы так же создадим новый обработчик события:
  Template.post.events({
    "click .remove": function () {
      Posts.remove(this._id);
    }
  });

… который будет привязан к соответствующей конпке в шаблоне записи.
<template name="post">
  <div class="panel">
    <h2>{{title}}</h2>
    <p>{{{text}}}</p>
    <span class="remove alert radius small button">Удалить</span>
    {{published}}
  </div>
</template>


Таким образом мы получили простейшее приложение в несколько строчек, с функционалом отображения, добавления и удаления записей.
Стоит заметить, что благодаря «реактивности» метеора, все операции с базой данных будут моментально отображаться у всех пользователей. Чтобы предотвратить такое поведение нужно удалить отвечающий за это дело пакет:
meteor remove autopublish

Пример простой, если не сказать примитивный. Но даже он показывает, что благодаря удобному интерфейсу, предоставляемому этим фреймворком, человек, достаточно далёкий от веб-разработки может использовать технологии, которые ещё несколько лет назад были доступны только высококвалифицированным разработчикам (сокеты, динамическое обновление, js на сервере, документо-ориентированные базы данных).
Однако по скепсису в комментариях к другим постам о Meteor можно говорить о том, что не всем по душе такое радикальное упрощение. Представители «старой гвардии» ворчат: «Ещё один фреймворк! Не канонiчно. Только ассемблер, только хардкор!». Как социологу, мне кажется, что такая позиция в некоторой степени является следствием нежелания терять свой исключительный статус профессионалов, работающих с node.js.
Однако я уверен, что движение в сторону понятности и упрощения — несомненное благо. Профессионалы, если они действительно являются таковыми, смогут выделиться на разросшемся рынке. А многие любители IT, занятые в других областях, и потому не имеющие времени для воплощения своих идей в этой сфере, получат замечательный инструмент для творчества и возможно создадут множество веб-приложений решающих их узкоспециальные проблемы, о которых профессиональный разработчик может и не знать.
P.S.: если сообществу интересна эта тема, можно написать ещё одну-две статьи с описанием внедрения дополнительного функционала блога: редактирование записей, добавление тэгов и категорий, создание учетных записей пользователей, разграничение прав доступа.
Tags:
Hubs:
+35
Comments 81
Comments Comments 81

Articles