鼬~~哩賀,我是寫程式的山姆老弟,前幾天跟大家一起實驗了用 importmap、webpack、esbuild 來安裝 bootstrap,今天來繼續延續 Rails 7 的研究,要試試看用 jsbundling-rails 這個 gem 來處理 JS,這個 gem 可以讓我們選擇四種處理 JS 的方法,第一個是預設的 importmap,第二個是最近很紅的 esbuild,第三個是 rollup,第四個是 webpack,我們今天要實驗的是選擇 esbuild 來使用 React JS 試試看,看用起來感覺怎麼樣,夠夠~
$ rails new rails7_react -j esbuild
在 Rails 7 中,如果沒有帶 -j,預設就是使用 importmap
$ rails g controller home index
把新的頁面設為首頁 config/routes.rb
Rails.application.routes.draw do
root 'home#index'
end
安裝 react,$ yarn add react react-dom
重整 js 結構,我們不要用預設的 stimulus 給的東東,所以把 app/javascript/controllers 資料夾整個刪掉
然後 Gemfile 的 stimulus-rails 和 turbo-rails 都可以註解掉了
# Gemfile
...
# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
# gem "turbo-rails"
# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
# gem "stimulus-rails"
...
把 React 的結構帶進來,手動創建 app/javascript/components 資料夾
再手動創建 app/javascript/components/hello.jsx,建立簡單的 react component
import React from "react";
export default () => (
<div>Hello World, React with Rails 7.</div>
);
在 app/javascript/application.js 引用剛寫好的 component,並指定到我們等等要新增在 view 的 div id = app 的地方
import React from 'react';
import { createRoot } from 'react-dom/client';
import Hello from './components/Hello';
const container = document.getElementById('app');
createRoot(container).render(<Hello/>);
// 舊的寫法是
// import 'react-dom';
// ReactDOM.render(
// <Hello/>,
// document.getElementById('app'),
// );
在 app/views/home/index.html.erb 補上用來放 react component 的 div tag
<!-- app/views/home/index.html.erb -->
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
<div id="app"></div>
萬事俱備,啟動 $ ./bin/dev,然後會發現報錯惹
23:05:19 web.1 | started with pid 6421
23:05:19 js.1 | started with pid 6422
23:05:19 js.1 | yarn run v1.22.19
23:05:19 js.1 | $ esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets --watch
23:05:19 web.1 | => Booting Puma
23:05:19 web.1 | => Rails 7.0.4 application starting in development
23:05:19 web.1 | => Run `bin/rails server --help` for more startup options
23:05:19 js.1 | ✘ [ERROR] The JSX syntax extension is not currently enabled
23:05:19 js.1 |
23:05:19 js.1 | app/javascript/application.js:7:2:
23:05:19 js.1 | 7 │ <Hello/>,
23:05:19 js.1 | ╵ ^
23:05:19 js.1 |
23:05:19 js.1 | The esbuild loader for this file is currently set to "js" but it must be set to "jsx" to be able to parse JSX syntax. You can use "--loader:.js=jsx" to do that.
23:05:19 js.1 |
23:05:19 js.1 | 1 error
23:05:19 js.1 | [watch] build finished, watching for changes...
這個錯誤告訴我們說 esbuild 目前沒有啟用 jsx 的擴充,所以就來啟用
從 ./bin/dev 的內容可以得知,設定檔是放在 Procfile.dev 裡,所以就到 Procfile.dev 改一下設定,補上 --loader:.js=jsx 這段
// Procfile.dev
web: bin/rails server -p 3000
js: yarn build --watch --loader:.js=jsx
重新啟動 $ ./bin/dev,這次就沒報錯了,打開 127.0.0.1:3000,確認一下 React component 有沒有 render 出來~
成功~

在 Rails 裡面使用 React 的感覺挺神奇的,但這樣還沒有什麼感覺,明天來多試試看 React 做點應用吧,我們明天見~