「猫でもわかるHotwire入門 Turbo編」の実践メモ
概要
Hotwireに入門したく、以下のチュートリアルを実施した。
環境
記事では以下のバージョンが対象であるが、自分は最新バージョンを使ったので、差分があった。
記事
Ruby: 3.1.0
Rails: 7.0.2
Turbo: 7.1.0
Stimulus: 3.0.1
turbo-rails: 1.0.1
stimulus-rails: 1.0.4
自分の環境
- Ruby: 3.3.4
- Rails: 7.2.2
- Turbo:8.0.10
- Stimulus: 3.2.2
- turbo-rails: 2.0.11
- stimulus-rails: 1.3.4
rails new
下記コマンドでrails new
を実行したところ、bun
がインストールできていなかったので一部の処理がスキップされた。
$ rails new cat-hotwire --css=bootstrap --skip-jbuilder --skip-action-mailbox --skip-action-mailer --skip-test --skip-active-storage --skip-action-text
ログ
rails new cat-hotwire --css=bootstrap --skip-jbuilder --skip-action-mailbox --skip-action-mailer --skip-test --skip-active-storage --skip-action-text
create
create README.md
create Rakefile
create .node-version
create .ruby-version
create config.ru
create .gitignore
create .gitattributes
create Gemfile
run git init -b main from "."
Initialized empty Git repository in /Users/yuma.ito/repositories/personal/cat-hotwire/.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/views/pwa/manifest.json.erb
create app/views/pwa/service-worker.js
create app/assets/images
create app/assets/images/.keep
create app/controllers/concerns/.keep
create app/models/concerns/.keep
create bin
create bin/brakeman
create bin/rails
create bin/rake
create bin/rubocop
create bin/setup
create Dockerfile
create .dockerignore
create bin/docker-entrypoint
create .rubocop.yml
create .github/workflows
create .github/workflows/ci.yml
create .github/dependabot.yml
create config
create config/routes.rb
create config/application.rb
create config/environment.rb
create config/cable.yml
create config/puma.rb
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_2.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/406-unsupported-browser.html
create public/422.html
create public/500.html
create public/icon.png
create public/icon.svg
create public/robots.txt
create tmp
create tmp/.keep
create tmp/pids
create tmp/pids/.keep
create vendor
create vendor/.keep
create storage
create storage/.keep
create tmp/storage
create tmp/storage/.keep
remove app/views/layouts/mailer.html.erb
remove app/views/layouts/mailer.text.erb
remove app/mailers
remove test/mailers
remove config/initializers/cors.rb
remove config/initializers/new_framework_defaults_7_2.rb
run bundle install --quiet
run bundle lock --add-platform=x86_64-linux
Writing lockfile to /Users/yuma.ito/repositories/personal/cat-hotwire/Gemfile.lock
run bundle lock --add-platform=aarch64-linux
Writing lockfile to /Users/yuma.ito/repositories/personal/cat-hotwire/Gemfile.lock
run bundle binstubs bundler
rails importmap:install
apply /Users/yuma.ito/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/importmap-rails-2.0.3/lib/install/install.rb
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
run bundle install --quiet
rails turbo:install stimulus:install
apply /Users/yuma.ito/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/turbo-rails-2.0.11/lib/install/turbo_with_importmap.rb
Import Turbo
append app/javascript/application.js
Pin Turbo
append config/importmap.rb
run bundle install --quiet
apply /Users/yuma.ito/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/stimulus-rails-1.3.4/lib/install/stimulus_with_importmap.rb
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 app/javascript/application.js
Pin Stimulus
Appending: pin "@hotwired/stimulus", to: "stimulus.min.js"
append config/importmap.rb
Appending: pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
append config/importmap.rb
Pin all controllers
Appending: pin_all_from "app/javascript/controllers", under: "controllers"
append config/importmap.rb
run bundle install --quiet
rails css:install:bootstrap
apply /Users/yuma.ito/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/cssbundling-rails-1.4.1/lib/install/bootstrap/install.rb
apply /Users/yuma.ito/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/cssbundling-rails-1.4.1/lib/install/install.rb
Build into app/assets/builds
create app/assets/builds
create app/assets/builds/.keep
append app/assets/config/manifest.js
Stop linking stylesheets automatically
gsub app/assets/config/manifest.js
append .gitignore
append .gitignore
Remove app/assets/stylesheets/application.css so build output can take over
remove app/assets/stylesheets/application.css
Add stylesheet link tag in application layout
unchanged app/views/layouts/application.html.erb
Add default package.json
create package.json
Add default Procfile.dev
create Procfile.dev
Ensure foreman is installed
run gem install foreman from "."
Successfully installed foreman-0.88.1
Parsing documentation for foreman-0.88.1
Done installing documentation for foreman after 0 seconds
1 gem installed
Add bin/dev to start foreman
create bin/dev
Install Bootstrap with Bootstrap Icons, Popperjs/core and Autoprefixer
create app/assets/stylesheets/application.bootstrap.scss
run bun add sass bootstrap bootstrap-icons @popperjs/core postcss postcss-cli autoprefixer nodemon from "."
No version is set for command bun
Consider adding one of the following versions in your config file at /Users/yuma.ito/.tool-versions
bun 1.0.11
bun 1.0.29
bun 1.1.4
insert config/initializers/assets.rb
Appending Bootstrap JavaScript import to default entry point
append app/javascript/application.js
Pin Bootstrap
append config/importmap.rb
insert config/initializers/assets.rb
append config/initializers/assets.rb
run bun run build:css:compile from "."
No version is set for command bun
Consider adding one of the following versions in your config file at /Users/yuma.ito/.tool-versions
bun 1.0.11
bun 1.0.29
bun 1.1.4
run bun run build:css:prefix from "."
No version is set for command bun
Consider adding one of the following versions in your config file at /Users/yuma.ito/.tool-versions
bun 1.0.11
bun 1.0.29
bun 1.1.4
run bun run build:css from "."
No version is set for command bun
Consider adding one of the following versions in your config file at /Users/yuma.ito/.tool-versions
bun 1.0.11
bun 1.0.29
bun 1.1.4
gsub Procfile.dev
run bundle install --quiet
run bun add sass bootstrap bootstrap-icons @popperjs/core postcss postcss-cli autoprefixer nodemon from "."
No version is set for command bun
Consider adding one of the following versions in your config file at /Users/yuma.ito/.tool-versions
bun 1.0.11
bun 1.0.29
bun 1.1.4
や
run bun run build:css:compile from "."
No version is set for command bun
Consider adding one of the following versions in your config file at /Users/yuma.ito/.tool-versions
bun 1.0.11
bun 1.0.29
bun 1.1.4
run bun run build:css:prefix from "."
No version is set for command bun
Consider adding one of the following versions in your config file at /Users/yuma.ito/.tool-versions
bun 1.0.11
bun 1.0.29
bun 1.1.4
run bun run build:css from "."
No version is set for command bun
Consider adding one of the following versions in your config file at /Users/yuma.ito/.tool-versions
bun 1.0.11
bun 1.0.29
bun 1.1.4
など
--css=bootstrap
を指定しているので、cssbundling-rails
によってBootstrapがインストールされる。
-j
は指定していないので、jsbundling-rails
ではなくデフォルトのimportmap-rails
が使われる。
本の方には
$ rails newのオプションで--css bootstrapを指定したけれども、その場合は自動的にjsbundling-railsを使うことになる
と記載があるが、jsbundling-rails
にはならなかった。(Railsのバージョンの違い?)
途中でインストールに失敗していたので、bunをインストールした後に下記コマンドを実行した
bun add sass bootstrap bootstrap-icons @popperjs/core postcss postcss-cli autoprefixer nodemon
Modal
がimportできずエラー
チュートリアル3の登録・編集機能でモーダル化する際にbootstrapのFailed to register controller: modal (controllers/modal_controller) SyntaxError: The requested module 'bootstrap' does not provide an export named 'Modal'
import mapsで正しくモジュールを読み込めていない?
importmap
にはbootstrap
は存在しているので、マッピングはうまくできていそうだが。
該当のコードは以下。
import {Controller} from "@hotwired/stimulus"
import {Modal} from "bootstrap"
// Connects to data-controller="modal"
export default class extends Controller {
// コントローラーがHTML要素にアタッチされたときに呼ばれる
connect() {
this.modal = new Modal(this.element);
this.modal.show();
}
close(event) {
if (event.detail.success) {
this.modal.hide();
}
}
}
config/importmap.rb
に以下の2行を追加した。
pin "bootstrap", to: "bootstrap.min.js", preload: true
pin "@popperjs/core", to: "popper.js", preload: true
config/assets.rb
に以下のコードを追加
Rails.application.config.assets.precompile += %w[bootstrap.min.js popper.js]
参考:
Gemfileにbootstrap
が入っていなかったので追加
gem "bootstrap"
やはり同じエラーになり原因がさっぱり分からなかったので、CDNから取得するとうまく行った
pin "bootstrap", to: "https://ga.jspm.io/npm:bootstrap@5.2.3/dist/js/bootstrap.esm.js"
{data: {controller: 'hoge'}}
を指定する条件は?
Stimulusで チュートリアル3の「編集・登録のモーダル化」にて{controller: 'modal'}
を指定していなかった。
<%= bootstrap_form_with(model: cat, data: { action: "turbo:submit-end->modal#close" }) do |form| %>
controller
を指定するときとしないときの違いを知りたい
Copilotに聞いてみた
Stimulusでdata-controllerを指定するときとしないときの違いは
Stimulus
でdata-controller
を指定する場合としない場合の違いは、以下の通りです。
data-controller
を指定する場合
data-controller
を指定すると、そのHTML要素に対して特定のStimulusコントローラーがアタッチされます。これにより、コントローラーのライフサイクルメソッド(例:connect
)やアクション(例:click
イベントに対応するメソッド)が実行されます。
例:
<div data-controller="modal">
<!-- この要素に対してmodal_controller.jsがアタッチされる -->
</div>
data-controller
を指定しない場合
data-controller
を指定しない場合、そのHTML要素にはStimulusコントローラーがアタッチされません。したがって、コントローラーのライフサイクルメソッドやアクションは実行されません。
例:
<div>
<!-- この要素にはコントローラーがアタッチされない -->
</div>
data-controller
を指定することで、特定のHTML要素に対してStimulusコントローラーの機能を適用することができます。
DOM要素とStimulusのコントローラーの紐づけを行っている模様。