背景
- 夏休みの時間を使ってインターン活動で得た経験を復習したいと考え,webアプリケーションを作成することにしました.
- 実際のアプリケーションの他に,記事を書くことで,備忘録的な役割を持たせつつ,自分が学習した知識をアウトプットできると考えました.
環境
- Ruby 3.2.0
- Ruby on Rails 7.0.6
事前学習
環境構築の方法とは直説的に関係がありませんが,今回の記事の目的に,学習内容のアウトプットも含まれているので,本記事内に書き残しました.(飛ばしてokです)
諸先輩方による大変わかりやすい記事を参考にしながら,環境構築の方法を調査しつつ,今まで目を逸らしてきたRailsプロジェクトで実装したフロントエンドが表示されるそもそもの仕組みを勉強しました.
学習内容のメモ
-
Railsプロジェクト環境下でフロントエンドを実装し,ブラウザ上に表示するには,以下の処理が必要であった.
- トランスパイル : JS以外のファイルをJSに変換する
- バンドリング : 後者はモジュールの依存関係を解決し,JSが動くようにする
-
Rsils6まではwebpacker(Rails用のwebpackを楽に使えるようにするツール)というgemが使われており,webpackがモジュールバンドラとしての役割を担ってくれていた.
-
Rails7では新たに,importmapsという仕組みが採用され,ブラウザがよしなに必要なファイル取得を行なってくれるので,バンドリングの処理が必要なくなった.(詳細は下記の参考文献をご覧ください.)
-
しかし,importmapsを利用する方法では,せいぜい「JSXのような形でJavaScriptを書けるようになる」だけで,JSX/TSXファイルは使うことができない. → 今回の環境構築の要件を満たすことができない
-
そこで,それらのファイルをトランスパイルして,要件を満たす(快適な)開発環境を構築するために,importmapsではなく,jsbundling-railsというビルドツールを使い,モジュールバンドらとして,esbuildを採用することで,TSXファイルを動かすことができるようになる.
要点
- Rails7から採用されたimportmapsではTSXファイルをトランスパイルすることができないので,別の方法を選択する必要がある.
- 代わりにjsbundling-railsというビルドツールを使ってesbuildをモジュールバンドラに設定する
- ↑により,本記事の要件を満たす,環境(=React,TypeScript導入後にバンドリング,トランスパイルを行い,TSXファイルに記載したスクリプトが動作する)を構築する.
環境構築の手順
参考にした記事
-
rails new!(新しいアプリケーションの作成)
下記のコマンドを実行すると,DBにpostgresqlに設定し,viewに.tsx
ファイルを使用できるようになる.$ rails new (your app name) -d postgresql --javascript=esbuild
-
Reactの導入
$ yarn add react react-dom
-
Gemfileの追加
Gemfileにjsbundling-rails
(github)という名前のgemを新たに追加するために下記の文言を追記Gemfilegem 'jsbundling-rails'
その後,gemをインストールする
$ bandle install
-
ビルドツールのインストール
(githubページの指示に従い)以下のコマンドを実行$ rails javascript:install:esbuild
実行結果
Compile into app/assets/builds create app/assets/builds create app/assets/builds/.keep append app/assets/config/manifest.js append .gitignore append .gitignore Add JavaScript include tag in application layout insert app/views/layouts/application.html.erb Add default Procfile.dev create Procfile.dev Ensure foreman is installed run gem install foreman from "." Fetching foreman-0.87.2.gem Successfully installed foreman-0.87.2 1 gem installed A new release of RubyGems is available: 3.4.1 → 3.4.18! Run `gem update --system 3.4.18` to update your installation. Add bin/dev to start foreman create bin/dev Install esbuild run yarn add esbuild from "." yarn add v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... warning " > tempusdominus-bootstrap-4@5.39.2" has unmet peer dependency "moment-timezone@^0.5.31". warning " > tempusdominus-bootstrap-4@5.39.2" has unmet peer dependency "tempusdominus-core@5.19.3". [4/4] Building fresh packages... success Saved lockfile. success Saved 2 new dependencies. info Direct dependencies └─ esbuild@0.19.1 info All dependencies ├─ @esbuild/linux-x64@0.19.1 └─ esbuild@0.19.1 $ husky install husky - Git hooks installed Done in 18.62s. Add build script Add "scripts": { "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=/assets" } to your package.json
-
package.json
に追記
4の実行結果の指示に従うpackage.json// 追記 "scripts": { "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets --target=esnext --loader:.png=file --loader:.js=jsx --loader:.ts=tsx", ... }, "dependencies": { ... "esbuild": "^0.19.1",
-
4の実行によって生成されたファイルの編集
(foreman 経由でのサーバーを起動する際の設定Procfile.devweb: bin/rails server -p 3000 -b 0.0.0.0 js: yarn build --watch
動作確認テスト
以下のファイルを作成して実際に表示されるかどうかを確認する.
(routeの設定方法等は割愛します.参考)
viewファイル
<div class="ly_container">
<div class="card mt-30">
<div class="de-top">
<p><strong>Home#index</strong></p>
</div>
</div>
<div id="homeIndex"></div>
<%= javascript_include_tag "HomeIndex", defer: true %>
</div>
<script language="javascript" type="text/javascript">
</script>
import { HelloReact } from 'app/javascript/components/HelloReact/HelloReact';
import React from 'react';
import ReactDOM from 'react-dom';
export const PostIndex = () => {
return (
<>
<HelloReact />
</>
);
};
ReactDOM.render(<PostIndex />, document.getElementById('postIndex'));
component
import React from 'react';
export const HelloReact = () => {
return (
<h1>Hello React!</h1>
)
}
設定ファイル
// Import and register all your controllers from the importmap under controllers/*
import { application } from "./application"
// Eager load all controllers defined in the import map under controllers/**/*_controller
// import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application)
// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
// lazyLoadControllersFrom("controllers", application)
bin/dev
コマンドでサーバーを立ち上げる,編集したファイルのviewくぉ表示すると以下のように表示された.
まとめ
動作確認のところでパスの指定等少々苦戦したものの,無事,RailsプロジェクトにReact,TypeScriptを導入することができました.
参考にさせていただいた記事のおかげで,技術背景なんかにも触れながら,比較的簡単に環境を構築することができました.
筆者自身学習をしながらの投稿になるので,所々文章が稚拙であったり,技術的な部分で誤りがあったりするかと思いますが,そのような箇所がございましたら,ご指摘いただけますと幸いです.
ここまで読んでくださりありがといございました.