Статьи

Автоматически перезагружать все вещи с охраной

Представьте себя в этой ситуации:

Сегодня в офисе оживленный день, и последние двенадцать часов вы работали над внешним проектом. Вам неоднократно приходилось проходить всю фазу сохранения-компиляции-перезагрузки с вашим браузером. И когда я говорю «компилировать», я имею в виду компиляцию тех файлов SCSS и CoffeeScript, которые вы так отчаянно хотели получить, с помощью серии кропотливых команд оболочки. «Я Рубин!», Кричите вы, «должен быть лучший путь!». Ну, есть. Позвольте мне представить вам Guard , ваш новый любимый камень Ruby для внешнего интерфейса.

Что такое гвардия?

Guard — это просто наблюдатель за файловой системой. Другими словами, он обнаруживает, когда вы сохраняете файл, а затем запускает команду. Это немного сложнее, но об этом мы поговорим позже.

Как охранник может мне помочь?

Помните тот сценарий, в котором вы только что были? Ну, на этот раз давайте вставим Guard в него:

Сегодня в офисе оживленный день, но вы не против, потому что вы только что закончили свой последний фронт-проект. На вашем постоянном столе (да, вы такой крутой ), у вас есть несколько открытых окон. На вашем большом мониторе ваш любимый редактор кода открыт с минимизированным терминалом для легкого доступа. На экране вашего ноутбука открыто окно браузера. Вам не приходилось прикасаться к этому окну часами, потому что Guard и LiveReload автоматически обновляют браузер на основе ваших изменений. Это включает в себя компиляцию вашего SCSS и CoffeeScript! Вы делаете глоток кофе и кричите «Я — Рубиист!», Глядя вокруг на своих коллег, которые все еще проходят фазу сохранения-компиляции-перезагрузки. Жизнь хороша, все благодаря Гвардии.

Вы хотите это? Конечно, вы делаете! Давайте начнем…

Установка Guard & Friends

Установка Guard так же проста, как и gem install guard . Тогда вы готовы к настройке.

Затем вы должны решить, какие плагины вы хотите. В этом уроке мы обсудим следующие плагины: (вам нужно будет установить их: gem install PLUGIN )

Каждый плагин немного отличается, но также очень похож. Когда вы узнаете, как настроить эти 5 плагинов, вы сможете настроить другие 267+ доступных защитных плагинов .

Для большинства проектов желательно иметь Gemfile для зависимостей. Вот как должен выглядеть ваш Gemfile если вы используете все плагины:

 source 'https://rubygems.org/' group :development do gem 'guard' gem 'guard-coffeescript' gem 'guard-sass' gem 'guard-less', git: 'git://github.com/guard/guard-less.git' gem 'therubyracer' gem 'guard-livereload' end 

Примечание. На данный момент необходимо создать гем без guard-less из git, потому что сопровождающие не выдвинули последнюю версию в RubyGems. Это может измениться, но сейчас это так. (см. выпуск № 16 ) Вы можете попробовать это без опции git , но я не могу гарантировать безошибочную установку. Кроме того, gem therubyracer требуется без guard-less , но не используется как зависимость, поэтому мы должны добавить его самостоятельно.

CoffeeScript

Ты Рубин Согласитесь, и синтаксис CoffeeScript в стиле Ruby завлек вас с самого начала. С guard-coffeescript вам больше не придется выбирать между уродливым JavaScript или уродливым процессом компиляции с CoffeeScript. Давайте инициализируем Guard с CoffeeScript:

 $ bundle exec guard init coffeescript 

Это создает файл конфигурации ( Guardfile ) для ваших «стражей» (плагинов). Давайте посмотрим внутрь:

 # A sample Guardfile # More info at https://github.com/guard/guard#readme guard 'coffeescript', :input => 'app/assets/javascripts' 

Это очень хорошо, но мы держим наш CoffeeScript в другом каталоге, чем скомпилированный JavaScript, поэтому давайте изменим файл:

 guard 'coffeescript', :input => 'coffee', :output => 'js' 

Обратите внимание, что мы добавили :output к опциям. Таким образом, CoffeeScript живет в каталоге coffee и компилируется в каталог js .

Начни охрану и посмотри наши файлы:

 $ bundle exec guard 

Добавьте немного CoffeeScript в наш проект и сохраните:

 # file: coffee/test.coffee console.log 'It worked!' 

Обратите внимание, что в терминале, когда вы сохраняете файл, он генерирует JavaScript в каталоге js :

 [1] guard(main)> 20:54:21 - INFO - Compile coffee/test.coffee 20:54:21 - INFO - 08:54:21 PM Successfully generated js/test.js 

Когда вы сохраняете любой файл *.coffee в каталоге coffee , Guard скомпилирует его в каталог js с тем же именем. Это так просто.

Sass / SCSS

Да ладно, мы все любим Sass / SCSS. Процесс очень похож на CoffeeScript. На самом деле, мы даже будем использовать тот же Guardfile . Плагин guard-sass действительно имеет шаблон init , но на этот раз мы сделаем его сами. К счастью, все довольно просто:

 guard 'sass', :input => 'scss', :output => 'css' 

Это та же конфигурация, что и для guard-coffeescript , и она делает то же самое. Все файлы Sass / SCSS внутри входного каталога (в данном случае scss ) будут скомпилированы в выходной каталог ( css ). Легко и приятно; так и должно быть.

Меньше

Конфигурация Less ‘немного отличается от guard-coffeescript и guard-sass . Он использует регулярные выражения и метод watch внутри блока. Это может показаться немного запутанным, но вы поймете через минуту.

 guard :less, output: 'css' do watch %r{^less/.*\.less$} end 

В этом примере показан блок guard :less с использованием метода watch . watch принимает регулярное выражение, которое соответствует всем файлам в проекте. В этом примере регулярное выражение соответствует всем файлам, которые находятся в каталоге less и имеют расширение .less . Если вы не знакомы с регулярными выражениями, вы можете поиграть с этим здесь . Обратите внимание, что %r{} и // оцениваются как регулярные выражения в Ruby. Однако с синтаксисом %r косые черты (‘/’) не нужно экранировать. Мы могли бы так же легко написать одно и то же:

 guard :less, output: 'css' do watch /^less\/.*\.less$/ end 

Давайте запустим Guard и проверим это:

 $ bundle exec guard 

Теперь создайте меньший файл в каталоге less .

 // file: less/foo.less @black: #000; body { background: @black; } 

После сохранения обратите внимание, что foo.css компилируется в каталог css из-за опции :output .
ГЕГ

LiveReload

Мы обработали предварительную компиляцию ресурсов, но как насчет «обновить» часть «сохранить-компилировать-обновить»? Скажи привет « guard-livereload , потому что это сделало твою жизнь намного проще.

Что такое LiveReload?
LiveReload — это утилита автообновления браузера. Guard сообщает об этом, когда файлы меняются, и LiveReload (в вашем браузере) автоматически обновляет страницу.

Установка
Мы уже включили guard-livereload в наш Gemfile , поэтому он должен быть установлен, но мы также должны установить расширение Chrome. Вы можете скачать его здесь. Теперь давайте настроим guard-livereload .

Вот список ресурсов, которые мы хотим перезагрузить при сохранении:

  • HTML
  • CSS
  • JS
  • PNG
  • JPG

Обратите внимание, что мы не включили Sass, SCSS, Less или CoffeeScript, потому что они будут скомпилированы и перезагружены LiveReload при их изменении. Это прекрасный цикл. Давайте создадим регулярное выражение, чтобы все это произошло.

Регулярное выражение: %r{^.*\.(html|css|js|png|jpg)$} . Не стесняйтесь проверить это на Rubular, чтобы убедиться, что он работает так, как мы хотим.

Поместите это в Guardfile примерно так:

 guard 'livereload' do watch %r{^.*\.(html|css|js|png|jpg)$} end 

Если мы сохраним какие-либо файлы, соответствующие регулярному выражению, браузер перезагрузит указанные файлы. Но сначала мы должны связать расширение с Guard. Для этого давайте создадим простой HTML-файл:

 <!DOCTYPE html> <html> <head> <title>Guard Rocks!</title> <link rel="stylesheet" href="css/foo.css"> </head> <body> <h1>Hello, Guard!</h1> </body> </html> 

Ничего особенного, просто хороший старый HTML. Поскольку это статический файл, вы можете посетить его, используя протокол file:// , но Chrome очень ограничивает расширение доступа к локальным файлам (и по уважительной причине), поэтому мы должны обслуживать наши файлы с помощью простого сервера. Руби на помощь еще раз!

Создайте файл с именем serve.rb в корне вашего проекта.

 # file: serve.rb require 'rack' server = Rack::Builder.new do run Rack::Directory.new(Dir.pwd) end Rack::Handler::WEBrick.run(server) 

Это простой сервер Rack / WEBrick, который будет размещать наши файлы на localhost:8080 . ruby serve.rb и все ruby serve.rb ! Вы можете выключить сервер в любое время с помощью control-C.

Теперь мы можем посетить это в нашем браузере по адресу localhost:8080/index.html . Чтобы подключить расширение к Guard, нажмите кнопку LiveReload на панели расширений браузера, и Guard должен вывести «Browser connected». Это не будет работать, пока браузер не подключен .

Допустим, мы хотим, чтобы текст в теле был белым. Все, что нам нужно сделать, это ввести color: #ffffff в наш селектор body . Как только это будет сделано, Guard скомпилирует ваш SCSS / Sass / Less в CSS и перезагрузит браузер, сразу же показывая ваши изменения. То же самое работает для файлов JavaScript / CoffeeScript. Потрясающие!

Уведомления

Я слышу, как ты кричишь на свой компьютер. Вы говорите: «Ух ты! Это супер круто! Я просто хотел бы получать уведомления на экране своего компьютера, чтобы мне не приходилось смотреть на свой терминал для подтверждения сборки ». К счастью для вас, Guard позволяет сделать это довольно легко. Тем не менее, он варьируется от системы к системе. Давайте начнем с моих любимых и наименее любимых операционных систем.

Примечание для АРЕНДАТОРОВ там:
Плагин Guard-LESS на данный момент не поддерживает уведомления. Это на самом деле ужасно поддерживается, так что если у вас есть немного свободного времени, возможно, раскошелиться.

Mac OS X

Для Mac мы будем использовать что-то под названием Growl . Следует отметить, что Growl не является бесплатным, но это с открытым исходным кодом. Поэтому, если 4 доллара (которые идут непосредственно на проект) слишком велики для вас, вы можете попробовать построить их самостоятельно. Вы можете найти инструкции для этого здесь , хотя это, вероятно, будет кропотливым процессом.

Установив Growl, добавьте gem 'ruby_gntp' в ваш Gemfile и bundle install . Guard и Growl отлично работают вместе, поэтому им не нужно ничего другого, кроме как запустить Growl:

 $ bundle exec guard 14:54:30 - INFO - Guard is using GNTP to send notifications. 14:54:30 - INFO - Guard is using TerminalTitle to send notifications. 14:54:30 - INFO - Guard::Less 1.0.0 is on the job! 14:54:30 - INFO - Guard::Less: compiling all files 14:54:30 - INFO - Guard::Less: Skipping less/foo.less because css/foo.css is already up-to-date 14:54:30 - INFO - Guard is now watching at '/path/to/project' 

Теперь, когда мы меняем файл, Growl + Guard сообщит нам.

Growl Notification from the Sass Plugin for Guard

Linux

Для Linux у нас есть два метода: Growl для Linux и Libnotify.

Growl для Linux

Установите Growl для Linux и добавьте gem 'ruby_gntp' в ваш Gemfile , затем запустите bundle exec guard и все Gemfile !

Libnotify

Установите libnotify-bin в вашем любимом менеджере пакетов ( sudo apt-get install libnotify-bin ), добавьте gem 'libnotify' в ваш Gemfile , затем запустите bundle exec guard .

Примечание. Это может работать не во всех дистрибутивах Linux.

Windows

Гвардия предлагает либо Growl для Windows, либо Snarl . После того, как вы установили один из них, просто добавьте gem 'ruby_gntp' в ваш Gemfile и Gemfile bundle exec guard .

Отказ от ответственности: я не проверял ни один из методов Windows и не могу гарантировать успех.

Рельсы (RSpec)

Вы начали пускать слюни при мысли о Guard on Rails, не так ли? Давайте сделаем это волшебство случиться . Ситуация похожа на описанную выше: вы работаете с приложением Rails и снова и снова запускаете одни и те же тестовые команды, что становится утомительным. Не волнуйся, у тебя охранник.

  1. Добавьте gem 'guard-rspec' в ваш Gemfilebundle install ).
  2. Запустите guard init rspec для создания стандартного леса проекта.
  3. Запустите bundle exec guard и наблюдайте за магией.

Это так просто. Тем не менее, я могу с уверенностью предположить, что вам нравится настраивать вещи, поэтому давайте немного Guardfile . Во-первых, вот что дает нам Guard:

 # A sample Guardfile # More info at https://github.com/guard/guard#readme # Note: The cmd option is now required due to the increasing number of ways # rspec may be run, below are examples of the most common uses. # * bundler: 'bundle exec rspec' # * bundler binstubs: 'bin/rspec' # * spring: 'bin/rsspec' (This will use spring if running and you have # installed the spring binstubs per the docs) # * zeus: 'zeus rspec' (requires the server to be started separetly) # * 'just' rspec: 'rspec' guard :rspec, cmd: 'bundle exec rspec' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec" } # Rails example watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } watch(%r{^spec/support/(.+)\.rb$}) { "spec" } watch('config/routes.rb') { "spec/routing" } watch('app/controllers/application_controller.rb') { "spec/controllers" } watch('spec/rails_helper.rb') { "spec" } # Capybara features specs watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" } # Turnip features and steps watch(%r{^spec/acceptance/(.+)\.feature$}) watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } end 

Вы можете решить, что хотите все эти вещи, но мне нравится немного упрощать вещи:

 guard :rspec, cmd: 'bundle exec rspec' do watch('spec/spec_helper.rb') { "spec" } watch('config/routes.rb') { "spec/routing" } watch('app/controllers/application_controller.rb') { "spec/controllers" } watch(%r{^spec/.+_spec\.rb$}) watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } end 

Это будет охватывать все (или, по крайней мере, большинство) тестов, которые обычно выполняются в приложении Rails. Это должно спасти вас и ваши пальцы от всех этих дополнительных испытаний. Одна вещь, которую я хотел бы отметить в этом коде, это опция cmd . Это указывает, какая тестовая команда будет запущена. В этой ситуации это bundle exec rspec , но он также может быть и bundle exec rake test ; каждый проект будет отличаться.

Как вы видели, Guard — это фантастический инструмент для всего автоматизированного. Вы можете наблюдать за изменениями в проекте, а затем компилировать, тестировать или даже перезагружать окно браузера. Избавь себя от разочарований и найди стражу .