2024-06-23
2024-06-23
rails に vite, TypeScript, React 導入
現在
importmaps にしている。ちゃんと bundle する形にしたい
importmaps だと React は jsx 使えないらしい(要出典)
参考
https://zenn.dev/salvage0707/scraps/1bd24c3293d85c
home#index
作る
エントリポイントが app/frontend/entrypoints/application.js
これを front/entrypoints にしたい。vite_rails でできるはず
yarn create vite frontend --template react-ts
を実行する。frontend directory ができるのだな
frontend/app/application.ts
はなんなんだろうか?
https://www.mof-mof.co.jp/tech-blog/2024/04/22/124028
これは TypeScript + React
front#index
を用意してその app/views/top/index.html.erb
にマウントする形
vite_rails
gem 'vite_rails' # vite_rails_legacy if using Rails 4
$ bundle install
If you upgraded the gem manually, please run:
bundle exec vite upgrade
# 一応やっておく
$ bundle exec vite upgrade
No such file or directory - npm
node 使える環境にしないといけない
.devcontainers/Dockerfile のほうにこれを追記
# Install Node.js and yarn
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y curl gnupg && \
curl -sL https://deb.nodesource.com/setup_current.x | bash - && \
apt-get install -y nodejs && \
npm install --global yarn && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /var/cache/apt/*
yarn のバージョンは 1.22.22
reinstall vite_rails
Gemfile から削除して
$ ./bin/bundle clean
$ ./bin/bundle
$ ./bin/bundle exec vite upgrade
Updating gems
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Resolving dependencies...
Fetching minitest 5.24.0 (was 5.23.1)
Fetching rack 3.1.4 (was 3.1.3)
Fetching zeitwerk 2.6.16 (was 2.6.15)
Fetching irb 1.13.2 (was 1.13.1)
Installing zeitwerk 2.6.16 (was 2.6.15)
Installing minitest 5.24.0 (was 5.23.1)
Installing rack 3.1.4 (was 3.1.3)
Installing irb 1.13.2 (was 1.13.1)
Bundle updated!
1 installed gem you directly depend on is looking for funding.
Run `bundle fund` for details
Upgrading npm packages # 今度はこけずに済んだぞ
added 31 packages in 8s
6 packages are looking for funding
run `npm fund` for details
$ ./bin/bundle exec vite install
Creating binstub
Check that your vite.json configuration file is available in the load path:
No such file or directory @ rb_sysopen - /workspaces/rails-playground/config/vite.json
Creating configuration files
Installing sample files
Installing js dependencies
added 1 package, and audited 33 packages in 962ms
6 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Adding files to .gitignore
Vite ⚡️ Ruby successfully installed! 🎉
bundle exec vite install で出来上がったファイルをみる
❯ git st
On branch introduce-vite_rails
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .gitignore
modified: Gemfile
modified: Gemfile.lock
modified: Procfile.dev
modified: app/views/layouts/application.html.erb
modified: config/initializers/content_security_policy.rb
# ここら辺が新たにできたファイル
Untracked files:
(use "git add <file>..." to include in what will be committed)
app/javascript/entrypoints/
bin/vite
config/vite.json
package-lock.json
package.json
vite.config.ts
編集されているファイルを見る
diff --git a/Procfile.dev b/Procfile.dev
index da151fe..e6ad037 100644
--- a/Procfile.dev
+++ b/Procfile.dev
@@ -1,2 +1,3 @@
web: bin/rails server
css: bin/rails tailwindcss:watch
+vite: bin/vite dev
# app/javascript/entrypoints/application.js がエントリポイントになるのだな
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 5374b55..366cfc6 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -16,6 +16,18 @@
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
+ <%= vite_client_tag %>
+ <%= vite_javascript_tag 'application' %>
+ <!--
+ If using a TypeScript entrypoint file:
+ vite_typescript_tag 'application'
+
+ If using a .jsx or .tsx entrypoint, add the extension:
+ vite_javascript_tag 'application.jsx'
+
+ Visit the guide for more information: https://vite-ruby.netlify.app/guide/rails
+ -->
+
</head>
<body>
diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb
index b3076b3..aa21c5f 100644
--- a/config/initializers/content_security_policy.rb
+++ b/config/initializers/content_security_policy.rb
@@ -11,7 +11,16 @@
# policy.img_src :self, :https, :data
# policy.object_src :none
# policy.script_src :self, :https
+ # Allow @vite/client to hot reload javascript changes in development
+# policy.script_src *policy.script_src, :unsafe_eval, "http://#{ ViteRuby.config.host_with_port }" if Rails.env.development?
+
+ # You may need to enable this in production as well depending on your setup.
+# policy.script_src *policy.script_src, :blob if Rails.env.test?
+
# policy.style_src :self, :https
+ # Allow @vite/client to hot reload style changes in development
+# policy.style_src *policy.style_src, :unsafe_inline if Rails.env.development?
+
# # Specify URI for violation reports
# # policy.report_uri "/csp-violation-report-endpoint"
# end
[54085 ms] Port forwarding 51341 > 45037 > 45037 stderr: Connection established
[55096 ms] rejected promise not handled within 1 second: Error: connect ECONNREFUSED 127.0.0.1:3000
stack trace: Error: connect ECONNREFUSED 127.0.0.1:3000
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1595:16)
[08:44:36] Error: connect ECONNREFUSED 127.0.0.1:3000
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1595:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3000
}
うーん、上記は bin/setup で実行されているが、どうもうまく動いていないなあ?
bin/dev だと foreman で起動してくれるのだが
08:47:30 web.1 | * Listening on http://127.0.0.1:3000
08:47:30 web.1 | * Listening on http://[::1]:3000
vite も3036 で立ち上がる。auto forwarded らしい。つまり .devcontainer.json の forwardPorts で指定していなくても良さそう
08:53:18 vite.1 | VITE v5.3.1 ready in 238 ms
08:53:18 vite.1 |
08:53:18 vite.1 | ➜ Local: http://localhost:3036/vite-dev/
08:53:18 vite.1 | ➜ press h + enter to show help
h
08:53:40 vite.1 |
08:53:40 vite.1 | Shortcuts
08:53:40 vite.1 | press r + enter to restart the server
08:53:40 vite.1 | press u + enter to show server url
08:53:40 vite.1 | press o + enter to open in browser
08:53:40 vite.1 | press c + enter to clear console
08:53:40 vite.1 | press q + enter to quit
# oはダメっぽい
o
08:53:56 vite.1 | Error: spawn xdg-open ENOENT
08:53:56 vite.1 | at ChildProcess._handle.onexit (node:internal/child_process:286:19)
08:53:56 vite.1 | at onErrorNT (node:internal/child_process:484:16)
08:53:56 vite.1 | at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
u
08:54:03 vite.1 |
08:54:03 vite.1 | ➜ Local: http://localhost:3036/vite-dev/
# ずっとリロード状態になって何にも確認できん
/workspaces/rails-playground/app/javascript/entrypoints/application.js を編集してみる
ログで Rebuilding… となるので HMR は効いているようだ?
layout file を application とは別に articles というものを用意していたので、そこで vite_javascript_tag などを設定しないといけなかった
とりあえず application, articles 両方で同じエントリポイントを読み込んでいるが、別々のほうがよかったりするのかな?
application layout を使用する別のコントローラーを用意しても良いかも
importmaps と vite_rails の併用
turbo-rails, stimulus は importmaps で入れている。。。のであればそれはそれで良さそう
vite_rails は完全に front 側を管理するのに徹すればいけるかな?
以下のようなエラーが devtools console で出てしまう。しかし type="module"
のスクリプトより先に読み込んでいるのだが…
An import map is added after module script load was triggered.
https://github.com/ElMassimo/vite_ruby/issues/417#issuecomment-1946414689
preload_links_header: false
にしないといけないのかなあ
entrypoints を変更する
app/javascript/entrypoints/application.ts
を front/entrypoints/application.ts
に変更する
https://vite-ruby.netlify.app/config/index.html#sourcecodedir
sourceCodeDir
を front
に変更する。エントリポイントはそこからの相対である entrypointsDir
front/entrypoints
に変更される
tailwind の設定ではこうなっている。front 側の React component にも適用されるのだろうか?
'./app/javascript/**/*.js',
importmaps と vite_rails の併用というか共存というか
importmaps -> Turbo を使っている 使いたくないところでは javascript_importmap_tags を使わなければ良いのでは? 別のレイアウトファイルを作って検証する
app/controllers/front/articles_controller.rb
class Front::ApplicationController < ApplicationController
layout 'front'
end
class Front::ArticlesController < Front::ApplicationController
layout 'front'
def index
end
end
front layout では vite_typescript_tag を使う
Turbo が効いているページから遷移してきた時はどうなるんだろう