Здесь, в carwow, мы посвящаем наши пятницы сторонним проектам, улучшениям производительности и внутренним инструментам.

В прошлую пятницу мы хотели создать простую панель управления, чтобы показать остальным сотрудникам компании наши коммиты Git.

Это была довольно простая задача — нам нужно было приложение для опроса списка коммитов через GitHub API и отображения его на странице.

Вместо проекта Rails мы решили использовать Метеор. Раньше я играл с этим фреймворком, поэтому я знал, что с его помощью легко создавать прототипы, и я хотел увидеть производственную систему (хотя и небольшую), использующую его.

Почему Метеор?

Одним из основных преимуществ использования Meteor является его реактивный характер. Проще говоря, «реактивный» означает, что если что-то меняется внутри фреймворка, все обновляется, как и ожидалось.

Например, когда код на сервере, CSS, клиентский код JavaScript или запись в базе данных обновляются, клиент получает уведомление и применяет изменения
в своей части, при этом пользователю не нужно обновлять страницу. страница.

Для этого Meteor поддерживает постоянное соединение между клиентами и сервером (через socketjs), и когда происходит изменение, сервер отправляет сообщение, говорящее клиенту обновить себя.

С другой стороны, клиент имеет локальную базу данных (называемую minimongo). Это позволяет клиенту сохранить копию необходимых ему данных. Таким образом, страницы отображаются без какого-либо явного взаимодействия с сервером.

Это делает чрезвычайно простым создание панели мониторинга: на стороне сервера нам просто нужно было опросить GitHub API, сохранить данные в базе данных и позволить фреймворку делать то, для чего он был создан.

Код

Логика приложения разделена на три основные области:

  • Получите историю коммитов с GitHub
  • Поделитесь данными с клиентом
  • Показать данные коммита в клиенте

Вы можете ознакомиться с нашим проектом на GitHub. Пожалуйста, не стесняйтесь предлагать идеи и сотрудничать.

Шаг 1. Получите историю коммитов с GitHub.

Мы написали простенькую обёртку для получения данных с GitHub, она находится в файле github_api.js.
Для опроса данных из API мы написали импортер, используя Meteor.setInterval():

// server/startup.js
function getCommits() {  
  let repos = Github.getRepos()

  repos.forEach( repo => {
    results = Github.getCommits(repo)
    deleteOldCommits(repo);
    saveCommits(repo, results);
  })
}

Meteor.startup(() => {  
  Meteor.setInterval(getCommits, 120000);
  getCommits()
})

Это удалит все данные из коллекции Commits и заменит их новым списком коммитов.

В Meteor код внутри папки клиента виден только клиенту, а код внутри папки сервера виден только серверу. Чтобы поделиться кодом между ними, вы можете поместить его в папку lib.

Мы использовали этот шаблон для определения нашей коллекции, поэтому нам не нужно было объявлять ее в обеих средах.

//lib/collections.js
Commits = new Mongo.Collection("commits")

Теперь на сервере нам нужно опубликовать данные, которые мы получили с GitHub:

// /server/publications.js
Meteor.publish("commits", function() {  
  return Commits.find({}, {limit: 20, sort: {date: -1}});
})

А на клиенте подписываемся на опубликованные данные — вот такой код нам нужно запустить:

// client/git_feed.js
Meteor.subscribe("commits");

Таким образом, клиент начнет получать данные с сервера и сохранит их в локальной базе данных mongo.

Шаг 3: представить данные

Meteor поставляется с собственным механизмом шаблонов под названием Blaze. По умолчанию работает как руль. Вместо того, чтобы использовать синтаксис руля по умолчанию, мы решили использовать Jade. Jade делает синтаксис похожим на haml:

// client/git_feed.jade

head  
  title git_feed 2
  link(href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet")
body  
  +header
  +commitList

template(name='header')  
  .header Latest changes

template(name='commitList')  
  ul.collection
    each commits
      +commitCard

template(name='commitCard')  
  li.commit
    .collection-item.avatar
      img.circle(src=author.avatar_url, alt='')
      span.title= author.name
      p!= escapeMessage(message)

У каждого шаблона могут быть свои хелперы, самое интересное здесь то, как мы показываем список коммитов:

Template.commitList.helpers({  
  commits() {
    return Commits.find({}, {sort: {date: -1}});
  }
});

В этом фрагменте вы можете увидеть, как хелпер возвращает записи из локальной коллекции.
Когда сервер обновляет коллекцию Commits, происходит следующее:

  • Сервер публикует обновления
  • Клиент получает уведомление и обновляет локальную базу данных
  • Функция commits() в клиенте выполняется, и страница перерисовывается.

Мы использовали Heroku для обслуживания нашего приложения. Чтобы настроить его под свои нужды, мы просто воспользовались доступным здесь билдпаком и следовали инструкциям. Судя по всему, теперь Heroku поддерживает веб-сокеты на нескольких динамиках, и вы можете просто добавить поддержку, используя heroku labs:enable http-session-affinity.
А вот скриншот приложения:

Meteor — относительно молодой фреймворк, и это можно заметить по ограниченному количеству инструментов, доступных из коробки. Маршрутизация, например, не поддерживается базовой структурой. Организация ваших файлов — еще одна проблема: в Meteor нет соглашений, помогающих организовать ваши файлы (по крайней мере, по сравнению с Rails). Хорошо иметь свободу, но более четко определенная структура может помочь вам ориентироваться в коде, написанном другими.

С другой стороны, у Meteor большое сообщество, поэтому то, что не предусмотрено основной командой, можно легко найти в огромном списке пакетов внутри Атмосферы.

Фреймворк прост в использовании, если вы не возражаете против написания кода js.

Первоначально опубликовано на сайте underthehood.carwow.co.uk 25 января 2016 г.

Заинтересованы в оказании влияния? Присоединяйтесь к команде carwow!
Чувствуете себя в обществе? Присоединяйтесь к нам в Twitter и LinkedIn :-)