Это руководство раскрывает опции для интегрирования функционала JavaScript в ваше приложение Rails, включая опции с использованием внешних пакетов JavaScript, а также как использовать Turbo с Rails.
После прочтения этого руководства вы узнаете:
Карты импорта позволяют импортировать модули JavaScript с помощью логических имен, которые направляют к версионированным файлам непосредственно из браузера. Карты импорта включены по умолчанию, начиная с Rails 7, позволяя каждому создавать современный приложения JavaScript с помощью большинства пакетов NPM без необходимости транспиляции или сборки.
Приложениям, использующим карты импорта, для функционирования не нужен Node.js или Yarn. Если планируете использовать Rails с importmap-rails
для управления зависимостями JavaScript, не нужно устанавливать Node.js или Yarn.
При использовании карт импорта не нужен отдельный процесс для сборки, просто запустите свой сервер с помощью bin/rails server
, и все заработает.
Importmap для Rails автоматически включен в Rails 7+ для новых приложений, но его также можно установить вручную в существующие приложения:
$ bin/bundle add importmap-rails
Запустите задачу установки:
$ bin/rails importmap:install
Чтобы добавить новые пакеты в приложение с картой импорта, запустите команду bin/importmap pin
из терминала:
$ bin/importmap pin react react-dom
Затем импортируйте пакет в application.js
как обычно:
import React from "react"
import ReactDOM from "react-dom"
Карты импорта по умолчанию в новом приложении Rails, но если предпочитаете традиционную сборку JavaScript, можете создать новые приложения Rails с esbuild, webpack или rollup.js на ваш выбор.
Для использования сборщика вместо карт импорта в новом приложении Rails, передайте опцию —javascript
или -j
в rails new
:
$ rails new my_new_app --javascript=webpack
ИЛИ
$ rails new my_new_app -j webpack
Каждая из опций сборки поставляется с простой конфигурацией и интеграцией в конвейер ресурсов с помощью гема jsbundling-rails.
При использовании опции сборки, используйте bin/dev
для запуска сервера Rails и создания JavaScript для development.
Если вы используете сборщик JavaScript в своем приложении Rails, должны быть установлены Node.js и Yarn.
Инструкции по установке можно найти на веб-сайте Node.js, а проверить, что он установлен корректно можно с помощью следующей команды:
$ node --version
Должна быть выведена версия вашего Node.js runtime. Убедитесь, что она выше, чем 8.16.0
.
Чтобы установить Yarn, следуйте инструкциям по установке на веб-сайте Yarn. Запуск этой команды должен вывести версию Yarn:
$ yarn --version
Если она сообщит что-то вроде 1.22.0
, Yarn был установлен корректно.
Когда создаете новое приложение Rails, нужно выбрать между картами импорта и решением со сборкой JavaScript. У каждого приложения имеются разные требования, и вам следует тщательно рассмотреть эти требования перед выбором варианта JavaScript, так как миграция от одной опции к другой может быть затратной по времени для больших, сложных приложений.
Карты импорта являются опцией по умолчанию, так как команда Rails верит в потенциал карт импорта для уменьшения сложности, улучшения опыта разработки и улучшения производительности.
Для многих приложений, особенно тех, что в основном полагаются на стек Hotwire для нужд JavaScript, карты импорта будут правильной опцией в долгосрочном плане. О причинах, лежащих в основе решения сделать карты импорта опцией по умолчанию в Rails 7, можно прочитать здесь.
Другим приложениям может все еще быть необходим традиционный сборщик JavaScript. Требования, сигнализирующие, что следует выбрать традиционный сборщик, включают:
esbuild
, если не указать другую опцию в rails new
.
Выберите ли вы карты импорта или традиционный сборщик, Rails поставляется с Turbo для ускорения приложения, значительно уменьшая объем JavaScript, который нужно было бы написать.
Turbo позволяет серверу доставлять непосредственно HTML, в качестве альтернативы превалирующим фронтенд фреймворкам, что уменьшает серверную часть вашего приложения Rails почти до JSON API.
Turbo Drive ускоряет загрузки страниц, избегая закрытия и пересоздания на каждом запросе навигации. Turbo Drive это улучшение и замена Turbolinks.
Turbo Frames позволяет предопределенным частям страницы быть обновленными по запросу, не влияя на остальное содержимое страницы.
Turbo Frames можно запросто использовать для встроенного редактирования без какого-либо пользовательского JavaScript, ленивой загрузки содержимого или создания интерфейса с вкладками, создаваемыми на сервере.
Rails предоставляет хелперы HTML для упрощения использования Turbo Frames с помощью гема turbo-rails.
Используя этот гем, можно добавить Turbo Frame в ваше приложение с помощью хелпера turbo_frame_tag
как тут:
<%= turbo_frame_tag dom_id(post) do %>
<div>
<%= link_to post.title, post_path(path) %>
</div>
<% end %>
Turbo Streams доставляет изменения страницы как фрагменты HTML, обернутые в самовыполняемые элементы <turbo-stream>
. Turbo Streams позволяют транслировать изменения, сделанные другими пользователями, по WebSockets и обновлять части страницы после отправки формы, без запроса загрузки полной страницы.
Rails предоставляет хелперы HTML и серверной части для упрощения использования Turbo Streams с помощью гема turbo-rails.
Используя этот гем, можно добавить Turbo Streams из экшна контроллера:
def create
@post = Post.new(post_params)
respond_to do |format|
if @post.save
format.turbo_stream
else
format.html { render :new, status: :unprocessable_entity }
end
end
end
Rails будет автоматически искать файл вью .turbo_stream.erb
и рендерить эту вью после нахождения.
Отклики Turbo Stream также могут рендериться внутри экшна контроллера:
def create
@post = Post.new(post_params)
respond_to do |format|
if @post.save
format.turbo_stream { render turbo_stream: turbo_stream.prepend('posts', partial: 'post') }
else
format.html { render :new, status: :unprocessable_entity }
end
end
end
Наконец, Turbo Streams могут быть инициализированы из модели или фоновой задачи с помощью встроенных хелперов. Эти трансляции могут быть использованы для обновления содержимого с помощью соединения WebSocket всем пользователям, сохраняя содержимое страницы актуальным и оживляя ваше приложение.
Чтобы транслировать Turbo Stream из модели, комбинируйте колбэк модели, наподобие:
class Post < ApplicationRecord
after_create_commit { broadcast_append_to('posts') }
end
С настроенным соединением WebSocket на странице, вы должны получить обновление наподобие:
<%= turbo_stream_from "posts" %>
Rails 6 поставлялся с инструментом с именем UJS, который позволял разработчикам переопределять метод тэгов <a>
, чтобы выполнять не-GET запросы после нажатия гиперссылки и добавлять диалоги подтверждения до запуска действия. Это было по умолчанию до Rails 7, но теперь рекомендуется использовать Turbo вместо этого.
Нажатие ссылок всегда приводит к запросу HTTP GET. Если приложение RESTful, некоторые ссылки фактически действия, изменяющие данные на сервере, и должны выполняться с помощью не-GET запросов. Этот атрибут позволяет помечать такие ссылки явным методом, таким как "post", "put" или "delete".
Turbo просканирует теги <a>
в приложении на атрибут данных turbo-method
и использует указанный метод при его наличии, переопределив действие GET по умолчанию.
Например:
<%= link_to "Delete post", post_path(post), data: { turbo_method: "delete" } %>
Это создаст:
<a data-turbo-method="delete" href="...">Delete post</a>
Альтернативой изменения метода ссылки с помощью data-turbo-method
является использование хелпера Rails button_to
. По причинам доступности, фактические кнопки и формы предпочтительнее для любых не-GET действий.
Можно спросить дополнительное подтверждение у пользователя, добавив атрибут data-turbo-confirm
на ссылки и формы. Пользователю будет представлен диалог JavaScript confirm()
, содержащий текст атрибута. Если пользователь выберет отмену, действие не произойдет.
Добавление этого атрибута на ссылках вызовет диалог при нажатии, а добавление его на формы вызовет его при отправке. Например:
<%= link_to "Delete post", post_path(post), data: { turbo_method: "delete", turbo_confirm: "Are you sure?" } %>
Это создаст:
<a href="..." data-turbo-confirm="Are you sure?" data-turbo-method="delete">Delete post</a>
В случае кнопок, атрибут data-turbo-confirm
обязан быть связан со сгенерированной формой, как в этом примере:
<%= button_to "Delete post", post, method: :delete, form: { data: { turbo_confirm: "Are you sure?" } } %>