Rails Hotwire 살펴보기: 터보 드라이브

18952 단어 rubywebdevrails
Turbolinks 기술이 Rails 4에서 처음 나왔을 때 어떤 사람들은 그것이 실제로 무엇인지 이해하지 못했습니다. Turbolinks가 출시되기 전(2011년경) 클라이언트 프로젝트 중 하나를 위해 Turbo Drive의 자체 버전을 개인적으로 구현했기 때문에 바로 얻을 수 있었기 때문에 Turbolinks가 출시되었을 때 정말 감사했습니다. Rails 7의 최신 업데이트에서 Turbolinks 기술은 더 이상 하이퍼링크를 가속화할 뿐만 아니라 양식 제출도 가속화하기 때문에 Turbo Drive(현재 Hotwire의 일부)로 이름이 변경되었습니다.

기본적으로 웹 응용 프로그램의 jQuery 프런트엔드 코드에서 매우 일반적인 패턴은 Ajax 호출을 실행하여 양식을 제출하거나 업데이트된 데이터를 요청한 다음 변경된 웹 페이지 부분만 업데이트하는 것입니다.

이를 구현하는 가장 수동적인 방법은 JSON 데이터를 반환하는 서버측 JSON API 리소스를 제공한 다음 Ajax 호출을 수행한 후 jQuery 코드가 해당 데이터를 수신하고 DOM 요소를 빌드하여 웹 페이지의 일부를 수동으로 업데이트하도록 하는 것입니다.

보다 간소화된 버전은 JavaScript에서 DOM 구축 작업을 수행할 필요 없이 직접 변경된 웹 페이지 부분을 업데이트하기 위해 jQuery Ajax 호출에서 사용할 이미 렌더링된 HTML 부분 스니펫을 반환하는 서버측 HTML 리소스를 구현하는 것입니다. .

내가 개인적으로 2011년경에 생각해낸 가장 간소화된 버전은 Ajax 호출을 한 후 시작하기 위해 현재 웹 페이지를 렌더링한 동일한 서버측 HTML 리소스를 단순히 재사용한 다음 변경된 HTML 요소만 잘라내는 것입니다. 전체 페이지 HTML을 반환하고 해당 요소를 사용하여 변경된 웹 페이지 부분을 업데이트합니다.

이제 이것이 오늘날 Turbo Drive이 수행하는 것과 거의 동일하므로 시작하기 위해 jQuery Ajax 코드나 JavaScript 코드를 작성할 필요조차 없습니다. 그것은 모두 당신을 위해 자동으로 발생합니다! 그러나 Turbo Drive은 기본적으로 변경된 부분만 자르는 대신 항상 전체 페이지의 본문을 바꿉니다. Turbo Drive이 페이지에서 자동으로 diffing을 수행했다면 좋았겠지만 그때까지는 Turbo Frames을 사용하여 해당 문제를 수동으로 해결할 수 있습니다(Turbo Frames은 이 블로그 게시물의 범위를 벗어납니다).

Turbo Drive 7에서 Rails을 살펴보겠습니다.
  • 레일 7 설치:

  • gem install rails -v7.0.2.3
    


    산출:

    Fetching tzinfo-2.0.4.gem
    Fetching i18n-1.10.0.gem
    Fetching thor-1.2.1.gem
    Fetching zeitwerk-2.5.4.gem
    Fetching method_source-1.0.0.gem
    Fetching concurrent-ruby-1.1.10.gem
    Fetching nokogiri-1.13.4-x86_64-darwin.gem
    Fetching activesupport-7.0.2.3.gem
    Fetching crass-1.0.6.gem
    Fetching loofah-2.16.0.gem
    Fetching rails-html-sanitizer-1.4.2.gem
    Fetching rails-dom-testing-2.0.3.gem
    Fetching rack-2.2.3.gem
    Fetching rack-test-1.1.0.gem
    Fetching erubi-1.10.0.gem
    Fetching builder-3.2.4.gem
    Fetching actionview-7.0.2.3.gem
    Fetching actionpack-7.0.2.3.gem
    Fetching railties-7.0.2.3.gem
    Fetching mini_mime-1.1.2.gem
    Fetching marcel-1.0.2.gem
    Fetching activemodel-7.0.2.3.gem
    Fetching activerecord-7.0.2.3.gem
    Fetching globalid-1.0.0.gem
    Fetching activejob-7.0.2.3.gem
    Fetching activestorage-7.0.2.3.gem
    Fetching actiontext-7.0.2.3.gem
    Fetching mail-2.7.1.gem
    Fetching actionmailer-7.0.2.3.gem
    Fetching actionmailbox-7.0.2.3.gem
    Fetching websocket-extensions-0.1.5.gem
    Fetching websocket-driver-0.7.5.gem
    Fetching nio4r-2.5.8.gem
    Fetching actioncable-7.0.2.3.gem
    Fetching rails-7.0.2.3.gem
    Successfully installed zeitwerk-2.5.4
    Successfully installed thor-1.2.1
    Successfully installed method_source-1.0.0
    Successfully installed concurrent-ruby-1.1.10
    Successfully installed tzinfo-2.0.4
    Successfully installed i18n-1.10.0
    Successfully installed activesupport-7.0.2.3
    Successfully installed nokogiri-1.13.4-x86_64-darwin
    Successfully installed crass-1.0.6
    Successfully installed loofah-2.16.0
    Successfully installed rails-html-sanitizer-1.4.2
    Successfully installed rails-dom-testing-2.0.3
    Successfully installed rack-2.2.3
    Successfully installed rack-test-1.1.0
    Successfully installed erubi-1.10.0
    Successfully installed builder-3.2.4
    Successfully installed actionview-7.0.2.3
    Successfully installed actionpack-7.0.2.3
    Successfully installed railties-7.0.2.3
    Successfully installed mini_mime-1.1.2
    Successfully installed marcel-1.0.2
    Successfully installed activemodel-7.0.2.3
    Successfully installed activerecord-7.0.2.3
    Successfully installed globalid-1.0.0
    Successfully installed activejob-7.0.2.3
    Successfully installed activestorage-7.0.2.3
    Successfully installed actiontext-7.0.2.3
    Successfully installed mail-2.7.1
    Successfully installed actionmailer-7.0.2.3
    Successfully installed actionmailbox-7.0.2.3
    Successfully installed websocket-extensions-0.1.5
    Building native extensions. This could take a while...
    Successfully installed websocket-driver-0.7.5
    Building native extensions. This could take a while...
    Successfully installed nio4r-2.5.8
    Successfully installed actioncable-7.0.2.3
    Successfully installed rails-7.0.2.3
    35 gems installed
    


  • 새 rails 블로그 앱을 만듭니다.

  • rails new blog_app
    


    산출:

          create  
          create  README.md
          create  Rakefile
          create  .ruby-version
          create  config.ru
          create  .gitignore
          create  .gitattributes
          create  Gemfile
             run  git init from "."
    Initialized empty Git repository in /Users/andymaleh/code/rails7/blog_app/.git/
          create  app
          create  app/assets/config/manifest.js
          create  app/assets/stylesheets/application.css
          create  app/channels/application_cable/channel.rb
          create  app/channels/application_cable/connection.rb
          create  app/controllers/application_controller.rb
          create  app/helpers/application_helper.rb
          create  app/jobs/application_job.rb
          create  app/mailers/application_mailer.rb
          create  app/models/application_record.rb
          create  app/views/layouts/application.html.erb
          create  app/views/layouts/mailer.html.erb
          create  app/views/layouts/mailer.text.erb
          create  app/assets/images
          create  app/assets/images/.keep
          create  app/controllers/concerns/.keep
          create  app/models/concerns/.keep
          create  bin
          create  bin/rails
          create  bin/rake
          create  bin/setup
          create  config
          create  config/routes.rb
          create  config/application.rb
          create  config/environment.rb
          create  config/cable.yml
          create  config/puma.rb
          create  config/storage.yml
          create  config/environments
          create  config/environments/development.rb
          create  config/environments/production.rb
          create  config/environments/test.rb
          create  config/initializers
          create  config/initializers/assets.rb
          create  config/initializers/content_security_policy.rb
          create  config/initializers/cors.rb
          create  config/initializers/filter_parameter_logging.rb
          create  config/initializers/inflections.rb
          create  config/initializers/new_framework_defaults_7_0.rb
          create  config/initializers/permissions_policy.rb
          create  config/locales
          create  config/locales/en.yml
          create  config/master.key
          append  .gitignore
          create  config/boot.rb
          create  config/database.yml
          create  db
          create  db/seeds.rb
          create  lib
          create  lib/tasks
          create  lib/tasks/.keep
          create  lib/assets
          create  lib/assets/.keep
          create  log
          create  log/.keep
          create  public
          create  public/404.html
          create  public/422.html
          create  public/500.html
          create  public/apple-touch-icon-precomposed.png
          create  public/apple-touch-icon.png
          create  public/favicon.ico
          create  public/robots.txt
          create  tmp
          create  tmp/.keep
          create  tmp/pids
          create  tmp/pids/.keep
          create  tmp/cache
          create  tmp/cache/assets
          create  vendor
          create  vendor/.keep
          create  test/fixtures/files
          create  test/fixtures/files/.keep
          create  test/controllers
          create  test/controllers/.keep
          create  test/mailers
          create  test/mailers/.keep
          create  test/models
          create  test/models/.keep
          create  test/helpers
          create  test/helpers/.keep
          create  test/integration
          create  test/integration/.keep
          create  test/channels/application_cable/connection_test.rb
          create  test/test_helper.rb
          create  test/system
          create  test/system/.keep
          create  test/application_system_test_case.rb
          create  storage
          create  storage/.keep
          create  tmp/storage
          create  tmp/storage/.keep
          remove  config/initializers/cors.rb
          remove  config/initializers/new_framework_defaults_7_0.rb
             run  bundle install
    Fetching gem metadata from https://rubygems.org/...........
    Resolving dependencies.......
    Fetching rake 13.0.6
    Installing rake 13.0.6
    Using concurrent-ruby 1.1.10
    Using builder 3.2.4
    Fetching racc 1.6.0
    Fetching minitest 5.15.0
    Using erubi 1.10.0
    Using crass 1.0.6
    Using rack 2.2.3
    Using nio4r 2.5.8
    Using websocket-extensions 0.1.5
    Using marcel 1.0.2
    Using mini_mime 1.1.2
    Fetching digest 3.1.0
    Fetching timeout 0.2.0
    Installing racc 1.6.0 with native extensions
    Installing digest 3.1.0 with native extensions
    Installing timeout 0.2.0
    Installing minitest 5.15.0
    Fetching strscan 3.0.1
    Fetching public_suffix 4.0.7
    Installing strscan 3.0.1 with native extensions
    Installing public_suffix 4.0.7
    Fetching bindex 0.8.1
    Installing bindex 0.8.1 with native extensions
    Fetching msgpack 1.5.1
    Using bundler 2.3.1
    Fetching matrix 0.4.2
    Installing msgpack 1.5.1 with native extensions
    Installing matrix 0.4.2
    Fetching regexp_parser 2.3.0
    Installing regexp_parser 2.3.0
    Fetching childprocess 4.1.0
    Installing childprocess 4.1.0
    Fetching io-console 0.5.11
    Installing io-console 0.5.11 with native extensions
    Using method_source 1.0.0
    Using thor 1.2.1
    Using zeitwerk 2.5.4
    Using rexml 3.2.5
    Fetching rubyzip 2.3.2
    Installing rubyzip 2.3.2
    Fetching sqlite3 1.4.2
    Installing sqlite3 1.4.2 with native extensions
    Using i18n 1.10.0
    Using tzinfo 2.0.4
    Using rack-test 1.1.0
    Fetching sprockets 4.0.3
    Installing sprockets 4.0.3
    Fetching puma 5.6.4
    Installing puma 5.6.4 with native extensions
    Using websocket-driver 0.7.5
    Using mail 2.7.1
    Fetching net-protocol 0.1.3
    Installing net-protocol 0.1.3
    Fetching addressable 2.8.0
    Installing addressable 2.8.0
    Using nokogiri 1.13.4 (x86_64-darwin)
    Fetching selenium-webdriver 4.1.0
    Installing selenium-webdriver 4.1.0
    Fetching reline 0.3.1
    Installing reline 0.3.1
    Using activesupport 7.0.2.3
    Fetching net-imap 0.2.3
    Installing net-imap 0.2.3
    Using net-pop 0.1.1
    Fetching net-smtp 0.3.1
    Installing net-smtp 0.3.1
    Using loofah 2.16.0
    Fetching xpath 3.2.0
    Installing xpath 3.2.0
    Fetching webdrivers 5.0.0
    Using rails-dom-testing 2.0.3
    Using globalid 1.0.0
    Using activemodel 7.0.2.3
    Fetching bootsnap 1.11.1
    Installing webdrivers 5.0.0
    Installing bootsnap 1.11.1 with native extensions
    Fetching irb 1.4.1
    Installing irb 1.4.1
    Using rails-html-sanitizer 1.4.2
    Fetching capybara 3.36.0
    Installing capybara 3.36.0
    Using activejob 7.0.2.3
    Using activerecord 7.0.2.3
    Fetching debug 1.5.0
    Installing debug 1.5.0 with native extensions
    Using actionview 7.0.2.3
    Using actionpack 7.0.2.3
    Fetching jbuilder 2.11.5
    Installing jbuilder 2.11.5
    Using actioncable 7.0.2.3
    Using activestorage 7.0.2.3
    Using actionmailer 7.0.2.3
    Using railties 7.0.2.3
    Fetching sprockets-rails 3.4.2
    Installing sprockets-rails 3.4.2
    Using actionmailbox 7.0.2.3
    Using actiontext 7.0.2.3
    Fetching importmap-rails 1.0.3
    Installing importmap-rails 1.0.3
    Fetching stimulus-rails 1.0.4
    Fetching turbo-rails 1.0.1
    Installing stimulus-rails 1.0.4
    Installing turbo-rails 1.0.1
    Fetching web-console 4.2.0
    Installing web-console 4.2.0
    Using rails 7.0.2.3
    Bundle complete! 15 Gemfile dependencies, 73 gems now installed.
    Use `bundle info [gemname]` to see where a bundled gem is installed.
             run  bundle binstubs bundler
           rails  importmap:install
    Add Importmap include tags in application layout
          insert  app/views/layouts/application.html.erb
    Create application.js module as entrypoint
          create  app/javascript/application.js
    Use vendor/javascript for downloaded pins
          create  vendor/javascript
          create  vendor/javascript/.keep
    Ensure JavaScript files are in the Sprocket manifest
          append  app/assets/config/manifest.js
    Configure importmap paths in config/importmap.rb
          create  config/importmap.rb
    Copying binstub
          create  bin/importmap
           rails  turbo:install stimulus:install
    Import Turbo
          append  app/javascript/application.js
    Pin Turbo
          append  config/importmap.rb
    Run turbo:install:redis to switch on Redis and use it in development for turbo streams
    Create controllers directory
          create  app/javascript/controllers
          create  app/javascript/controllers/index.js
          create  app/javascript/controllers/application.js
          create  app/javascript/controllers/hello_controller.js
    Import Stimulus controllers
          append  pp/javascript/application.js
    Pin Stimulus
    Appending: pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true"
          append  config/importmap.rb
    Appending: pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
          append  config/importmap.rb
    Pin all controllers
    Appending: pin_all_from "app/javascript/controllers", under: "controllers"
          append  config/importmap.rb
    


  • 블로그 게시물 스캐폴딩 생성:

  • cd blog_app
    rails g scaffold blog_post title:string body:text
    


    산출:

          invoke  active_record
          create    db/migrate/20220418153744_create_blog_posts.rb
          create    app/models/blog_post.rb
          invoke    test_unit
          create      test/models/blog_post_test.rb
          create      test/fixtures/blog_posts.yml
          invoke  resource_route
           route    resources :blog_posts
          invoke  scaffold_controller
          create    app/controllers/blog_posts_controller.rb
          invoke    erb
          create      app/views/blog_posts
          create      app/views/blog_posts/index.html.erb
          create      app/views/blog_posts/edit.html.erb
          create      app/views/blog_posts/show.html.erb
          create      app/views/blog_posts/new.html.erb
          create      app/views/blog_posts/_form.html.erb
          create      app/views/blog_posts/_blog_post.html.erb
          invoke    resource_route
          invoke    test_unit
          create      test/controllers/blog_posts_controller_test.rb
          create      test/system/blog_posts_test.rb
          invoke    helper
          create      app/helpers/blog_posts_helper.rb
          invoke      test_unit
          invoke    jbuilder
          create      app/views/blog_posts/index.json.jbuilder
          create      app/views/blog_posts/show.json.jbuilder
          create      app/views/blog_posts/_blog_post.json.jbuilder
    


  • 데이터베이스 마이그레이션:

  • rails db:migrate
    


    산출:

    == 20220418153744 CreateBlogPosts: migrating ==================================
    -- create_table(:blog_posts)
       -> 0.0039s
    == 20220418153744 CreateBlogPosts: migrated (0.0041s) =========================
    


  • Rails 서버 시작:

  • rails s
    


    산출:

    => Booting Puma
    => Rails 7.0.2.3 application starting in development 
    => Run `bin/rails server --help` for more startup options
    Puma starting in single mode...
    * Puma version: 5.6.4 (ruby 3.0.2-p107) ("Birdie's Version")
    *  Min threads: 5
    *  Max threads: 5
    *  Environment: development
    *          PID: 26666
    * Listening on http://127.0.0.1:3000
    * Listening on http://[::1]:3000
    Use Ctrl-C to stop
    


  • 홈페이지 방문 http://localhost:3000


  • http://localhost:3000/blog_posts에서 블로그 게시물 인덱스 방문


  • 3개의 블로그 게시물 작성:


  • 웹 브라우저 개발자 도구를 열고 네트워크 탭으로 이동합니다.


  • 블로그 게시물을 표시하고 모든 페이지 리소스를 새로 고치지 않고 Turbo Drive로 인해 네트워크 호출이 몇 번만 이루어졌는지 확인합니다.


  • 웹 브라우저에서 페이지를 새로 고치고 네트워크 탭에서 모든 리소스가 어떻게 로드되었는지 확인합니다.


  • 블로그 게시물을 편집하고 Network 탭을 지웁니다(개발자 도구 상단의 두 번째 행에 있는 두 번째 버튼을 클릭).


  • 양식을 제출하여 블로그 게시물을 업데이트하고 모든 페이지 리소스를 새로 고치지 않고 Turbo Drive로 인해 네트워크 호출이 몇 번만 이루어졌는지 확인합니다.



  • 그리고 그게 전부입니다!

    Turbo Drive에서 Rails 7 HotwireTurbo Handbook에 대해 자세히 알아보십시오.

    좋은 웹페이지 즐겨찾기