JavaScript 코드를 작성하지 않고도 페이지 변경 및 양식 제출 속도를 높이고 복잡한 페이지를 구성 요소로 나누는 방법을 찾고 있다면 이 게시물을 통해 Hotwire를 사용하여 Rails를 한 단계 끌어올릴 수 있습니다. 이 문서에서는 서버 측 렌더링 도구를 사용하는 방법을 알려줍니다.
핫와이어란 무엇입니까?
Hotwire는 유선을 통해 JSON 대신 HTML을 전송하여 JavaScript를 작성하지 않고도 최신 웹 애플리케이션을 구축할 수 있는 방법을 제공하므로 페이지 로드 속도가 빨라집니다. Rails는 기존의 단일 페이지 애플리케이션(SPA)과 관련된 속도나 응답성을 저하시키지 않으면서 항상 해당 기술에 통합했기 때문에 서버 측에서 렌더링을 유지 관리하고 더 간단하고 생산적인 개발 경험을 제공합니다.
Hotwire의 핵심은 Turbo gem입니다. 페이지 탐색 및 양식 제출 속도를 높이고 복잡한 페이지를 구성 요소로 나누고 WebSocket(ActionCable, 채널 및 스트리밍 데이터로 구성됨)을 통해 페이지의 부분 업데이트를 전송하는 보완 기술 세트입니다.
왜 사용해야 합니까?
JavaScript로 어려움을 겪고 있고 페이지 사이를 훨씬 빠르게 탐색하는 느낌을 통해 더 나은 사용자 경험을 활용하려면 Hotwire가 대안입니다.
핫와이어는 어떻게 작동합니까? Hotwire는 SSR(서버 측 렌더링)을 사용하여 주요 이점을 유지하면서 SPA와 관련된 일부 문제를 해결합니다. SSR은 렌더링 프로세스를 반대로 하여 기존 로딩과 유사한 SPA 렌더링 노력의 일부를 서버로 가져옵니다. SSR은 일부 렌더링이 서버에서 수행되기 때문에 사용자에게 보다 효율적인 애플리케이션 로드를 제공할 수 있습니다. 성능 향상 가능성 외에도 색인 생성과 같은 일부 SEO 문제를 처리하는 데 도움이 됩니다.
사용이 간편합니까?
사용이 매우 간단합니다. Rails 프로젝트의 기본 패키지(Ruby, RoR, ActionCable, WebSocket), 모든 JS 종속성을 다운로드하는 Turbo gem, WebSocket을 탐색하는 동안 임시 데이터를 저장할 Redis만 있으면 됩니다.
Turbo는 Turbo Drive, Frames, Streams 및 Native로 보완되기 때문에 단일 페이지 웹 애플리케이션의 속도를 갖기 위해 다른 언어(JS)를 배울 필요가 없습니다. 드라이브는 링크와 형태의 속도를 높이고 네트워크를 다시 로드할 필요성을 줄입니다. 반면 Frames는 네트워크를 로드하기 쉬운 독립적인 컨텍스트로 나눕니다.
Rails와 함께 어떻게 사용되나요?
이 섹션에서는 단계별 예를 보여줍니다.
이 예에서는 다음이 필요합니다.
- 루비
- 루비 온 레일즈
- 레디스
- SQLite(기본 데이터베이스)
- 보석 핫와이어
- 터보레일
- StimulusJS
- 웹소켓
- 액션 케이블
어떤 프로젝트를 만들까요?
소셜 미디어 프로젝트를 만들 것입니다.
먼저 터미널을 엽니다. 새로운 레일 프로젝트부터 시작하겠습니다.
rails new social-media
프로젝트 입력:
cd social-media
핫와이어 추가
프로젝트에 Hotwire gem 추가:
bundle add hotwire-rails
또는 Gemfile
을 엽니다. 다음을 추가하십시오:
gem "hotwire-rails"
두 번째 옵션을 사용하는 경우 지금 번들을 실행해야 합니다.
bundle install
그런 다음 설치합니다.
rails hotwire:install
초기 설정
이제 Hotwire가 만든 초기 설정을 분석할 좋은 시간입니다. Gemfile을 방문하면 다음과 같아야 합니다.
gem 'redis', '~> 4.0'
왜 Redis가 필요한가요?
WebSocket을 탐색하는 동안 ActionCable이 일부 임시 데이터를 저장해야 하기 때문에 Redis gem이 추가되었습니다. 그러나 Redis를 설치하는 것만으로는 충분하지 않습니다. 올바르게 구성되었는지 확인해야 합니다. config/cable.yml
로 이동하면 파일은 다음과 같아야 합니다.
development:
adapter: redis
redis://localhost:6379/1
애플리케이션을 시작할 때 Redis가 실행 중인지 확인하십시오(redis-server
).
JS 종속성
package.json
에 대한 종속성 확인 :
dependencies: {
@hotwired/turbo-rails: ^7.0.0-beta.5,
@rails/actioncable: ^6.0.0,
@rails/activestorage: ^6.0.0,
@rails/ujs: ^6.0.0,
@rails/webpacker: 4.3.0,
stimulus: ^2.0.0
}
모델 생성
모든 파일을 확인한 후 views
를 생성합니다. , controllers
, models
및 migrations
posts
body
이 있는 테이블 , 및 likes
열. 이렇게 하려면 터미널에서 다음을 실행하십시오.
rails g scaffold posts body:text likes:integer
데이터베이스 생성
이제 모든 것이 생성되었으므로 이러한 변경 사항을 데이터베이스로 보내야 하므로 터미널에서 다음을 실행합니다.
rails db:create db:migrate
모든 것이 잘 되면 서버(rails server
) 모든 것이 정상인지 확인하십시오. 이를 위해 서버를 실행한 다음 posts
을 방문합니다. 페이지는 https://localhost:3000/posts
가 됩니다. :
게시물 디렉토리의 인쇄 화면
게시물 나열
이제 게시물을 나열하겠습니다. 이를 위해 app/views/posts/_post.html.erb
를 생성합니다. 파일에 다음 코드를 추가합니다.
<div style="background: lightgrey; width: 300px; padding: 10px;">
<%= post.body %>
<br>
<%= link_to :edit, edit_post_path(post) %>
<%= button_to "likes (#{post.likes || 0})", post_path(post, like: true), method: :put %>
</div>
<br>
검증
body 필드(null일 수 없음)의 유효성을 검사해야 하며, 브로드캐스트에 트윗을 생성한 후 첫 번째 트윗과 동일한 화면에 표시하도록 지시할 것입니다. 이를 위해 app/models/post.rb
파일을 편집합니다. 다음 코드를 삽입하십시오:
class Post < ApplicationRecord
validates_presence_of :body
after_create_commit { broadcast_prepend_to :posts }
end
주문
게시물을 주문해야 하므로 컨트롤러(app/controllers/posts_controller.rb
).
...
def index
@posts = Post.all.order(created_at: :desc)
@post = Post.new
end
...
마무리
이제 index
를 수정해 보겠습니다. (app/views/posts/index.html.erb
) new post
표시 페이지 및 모든 posts
목록 .
<%= turbo_stream_from :posts %>
<%= turbo_frame_tag :post_form do %>
<%= render 'posts/form', post: @post %>
<% end %>
<%= turbo_frame_tag :posts do %>
<%= render @posts %>
<% end %>
색인으로 리디렉션
마지막으로 create
우리 컨트롤러의 메소드. show post
로 리디렉션되는 것을 방지하려면 페이지, 모든 것을 같은 페이지에 유지합시다.
...
def create
@post = Post.new(post_params)
respond_to do |format|
if @post.save
format.html { redirect_to posts_path }
format.json { render :show, status: :created, location: @post }
else
format.turbo_stream { render turbo_stream: turbo_stream.replace(@post, partial: 'posts/form', locals: { post: @post }) }
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
...
최종 페이지는 다음과 같아야 합니다.
최종 페이지 인쇄 화면
로그 확인
게시물이 작성되면 터미널 로그를 확인하십시오. 다음과 같이 표시되어야 합니다.
[ActionCable] Broadcasting to posts: "<turbo-stream action=\"prepend\" target=\"posts\"><template><div style=\"background: lightgrey; width: 300px; padding: 10px;\">\n first post\n <br>\n <a href=\"/posts/1/edit\">edit</a>\n <form class=\"button_to\" method=\"post\" action=\"/posts/4?like=true\"><input type=\"hidden\" name=\"_method\" value=\"put\" /><input type=\"submit\" value=\"likes (0)\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"<token>==\" /></form>\n</div>\n<br>\n</template></turbo-stream>"
생각
이는 ActionCable이 다음과 같이 초고속 성능으로 터보 스트림으로 작업하고 있음을 의미합니다. Completed 302 Found in 18ms
.
배포
Rails 서버와 함께 실행할 다른 실행 파일이 필요합니까?
아니요. ActionCable은 Unicorn, Puma 및 Passenger와 같은 인기 있는 서버에서 잘 작동하기 때문입니다.
Heroku는 Hotwire를 지원합니까?
예, Heroku는 Hotwire(웹 소켓) 기반을 지원합니다. 더 궁금한 사항이 있으시면 Heroku의 공식 문서를 확인하세요.
Redis를 사용하는 이유가 궁금하시다면 이유가 하나 더 있습니다.
Redis 없이 Heroku를 사용하는 경우 앱이 단일 dyno 이상으로 확장될 때 메시지가 모든 사람에게 전송되지 않습니다. 현재 앱의 상태 비저장 특성으로 인해 첫 번째 dyno에 연결된 클라이언트는 연결된 클라이언트가 보낸 메시지를 받지 못합니다. 두 번째 다이노에게. Redis는 메시지 상태를 전역 저장소에 저장하여 이 문제를 해결합니다.
Heroku에서 Redis 설정
원격 Redis 인스턴스로 Redis CLI 세션을 설정하려면 heroku redis:cli
를 사용하세요. .인스턴스를 지정하지 않으면 REDIS_URL
에 있는 인스턴스 기본적으로 사용됩니다. 둘 이상의 인스턴스가 있는 경우 연결할 인스턴스를 지정하십시오.
애플리케이션 서버에서 어떻게 작동합니까?
Redis pub-sub 시스템을 사용하려면 각 dyno를 설정해야 합니다. 모든 dyno는 동일한 채널(기본값)을 구독하고 메시지를 기다립니다. 각 서버가 메시지를 받으면 연결된 클라이언트에 게시할 수 있습니다. subscribe
에 대해 알아보겠습니다. 별도의 스레드에서 subscribe
로 차단 기능이므로 메시지를 기다리면 실행 흐름이 중지됩니다. 또한 연결에서 구독 명령이 만들어지면 연결이 구독을 취소하거나 메시지를 받을 수만 있기 때문에 두 번째 Redis 연결이 필요합니다. 여기에서 확장에 대해 자세히 알아보세요.
보안
현재 애플리케이션은 많은 공격에 노출되어 있으며 취약합니다. WSS를 설정하고 입력을 삭제하십시오. 여기에서 WebSocket 보안에 대해 자세히 알아보세요.
결론
여기에 표시된 것처럼 새 응용 프로그램을 통해 Hotwire를 사용할 수 있지만 Turbolinks에서 업데이트할 수도 있습니다.
이 기사는 "마법의 프레임워크"가 어떻게 작동하는지 이해하는 데 도움이 되었을 것입니다. 그 안에 WebSocket을 통한 조작 및 탐색이 포함된 집계된 터보 스트림을 통해 요청을 표시하는 작은 간단한 응용 프로그램을 실제로 개발할 수 있는 가능성이 있었습니다.