Ruby on Rails 7 では webpacker が廃止されました。
この記事では JS のバンドラーとして webpack を使って Rails 7 を構成する方法を説明します。
- Ruby 3.0.3
- Ruby on Rails 7.0.0
- Docker Desktop
プロジェクトディレクトリを作成し bundler で rails をインストールします。
% mkdir rails7-webpack-sample && cd -
% echo "source 'https://rubygems.org'\n\ngem 'rails', '~> 7.0.0'" > Gemfile
% bundle install
rails new
のオプションは次のようになっています。
% bundle exec rails new -h
Usage:
rails new APP_PATH [options]
Options:
[--skip-namespace], [--no-skip-namespace] # Skip namespace (affects only isolated engines)
[--skip-collision-check], [--no-skip-collision-check] # Skip collision check
-r, [--ruby=PATH] # Path to the Ruby binary of your choice
# Default: /Users/hiroki.toyokawa/.asdf/installs/ruby/2.7.2/bin/ruby
-m, [--template=TEMPLATE] # Path to some application template (can be a filesystem path or URL)
-d, [--database=DATABASE] # Preconfigure for selected database (options: mysql/postgresql/sqlite3/oracle/sqlserver/jdbcmysql/jdbcsqlite3/jdbcpostgresql/jdbc)
# Default: sqlite3
-G, [--skip-git], [--no-skip-git] # Skip .gitignore file
[--skip-keeps], [--no-skip-keeps] # Skip source control .keep files
-M, [--skip-action-mailer], [--no-skip-action-mailer] # Skip Action Mailer files
[--skip-action-mailbox], [--no-skip-action-mailbox] # Skip Action Mailbox gem
[--skip-action-text], [--no-skip-action-text] # Skip Action Text gem
-O, [--skip-active-record], [--no-skip-active-record] # Skip Active Record files
[--skip-active-job], [--no-skip-active-job] # Skip Active Job
[--skip-active-storage], [--no-skip-active-storage] # Skip Active Storage files
-C, [--skip-action-cable], [--no-skip-action-cable] # Skip Action Cable files
-A, [--skip-asset-pipeline], [--no-skip-asset-pipeline] # Indicates when to generate skip asset pipeline
-a, [--asset-pipeline=ASSET_PIPELINE] # Choose your asset pipeline [options: sprockets (default), propshaft]
# Default: sprockets
-J, [--skip-javascript], [--no-skip-javascript] # Skip JavaScript files
[--skip-hotwire], [--no-skip-hotwire] # Skip Hotwire integration
[--skip-jbuilder], [--no-skip-jbuilder] # Skip jbuilder gem
-T, [--skip-test], [--no-skip-test] # Skip test files
[--skip-system-test], [--no-skip-system-test] # Skip system test files
[--skip-bootsnap], [--no-skip-bootsnap] # Skip bootsnap gem
[--dev], [--no-dev] # Set up the application with Gemfile pointing to your Rails checkout
[--edge], [--no-edge] # Set up the application with Gemfile pointing to Rails repository
--master, [--main], [--no-main] # Set up the application with Gemfile pointing to Rails repository main branch
[--rc=RC] # Path to file containing extra configuration options for rails command
[--no-rc], [--no-no-rc] # Skip loading of extra configuration options from .railsrc file
[--api], [--no-api] # Preconfigure smaller stack for API only apps
[--minimal], [--no-minimal] # Preconfigure a minimal rails app
-j, [--javascript=JAVASCRIPT] # Choose JavaScript approach [options: importmap (default), webpack, esbuild, rollup]
# Default: importmap
-c, [--css=CSS] # Choose CSS processor [options: tailwind, bootstrap, bulma, postcss, sass... check https://github.com/rails/cssbundling-rails]
-B, [--skip-bundle], [--no-skip-bundle] # Don't run bundle install
Runtime options:
-f, [--force] # Overwrite files that already exist
-p, [--pretend], [--no-pretend] # Run but do not make any changes
-q, [--quiet], [--no-quiet] # Suppress status output
-s, [--skip], [--no-skip] # Skip files that already exist
Rails options:
-h, [--help], [--no-help] # Show this help message and quit
-v, [--version], [--no-version] # Show Rails version number and quit
Description:
The 'rails new' command creates a new Rails application with a default
directory structure and configuration at the path you specify.
You can specify extra command-line arguments to be used every time
'rails new' runs in the .railsrc configuration file in your home directory,
or in $XDG_CONFIG_HOME/rails/railsrc if XDG_CONFIG_HOME is set.
Note that the arguments specified in the .railsrc file don't affect the
defaults values shown above in this help message.
Example:
rails new ~/Code/Ruby/weblog
This generates a skeletal Rails installation in ~/Code/Ruby/weblog.
必要なものだけに絞って rails new .
します(お好みで変更してください)。
既に作成した Gemfile
を上書きするので --force
オプションを指定します。
下記の例ではデータベースとして MySQL を指定しています。
% bundle exec rails new . \
--force \
--database=mysql \
--skip-action-mailer \
--skip-action-mailbox \
--skip-action-text \
--skip-active-job \
--skip-active-storage \
--skip-action-cable \
--skip-hotwire \
--skip-jbuilder \
--javascript=webpack
開発環境は Docker Compose を使って構築します。
下記の内容で Dockerfile
を作成します。
FROM node:17.3-slim AS node
FROM node:17.3-slim AS build-node-modules
WORKDIR /app
COPY package.json /app/
COPY yarn.lock /app/
RUN yarn install
FROM ruby:3.0.3-slim AS ruby-base
WORKDIR /app
ENV BUNDLE_APP_CONFIG .bundle
ENV BUNDLE_PATH vendor/bundle
# For nokogiri
# https://nokogiri.org/tutorials/installing_nokogiri.html#installing-using-standard-system-libraries
# For mysql
# https://github.com/brianmario/mysql2#linux-and-other-unixes
RUN apt-get update -y && apt-get install -y \
build-essential \
pkg-config libxml2-dev libxslt-dev \
libmariadb-dev default-mysql-client
FROM ruby-base AS build-ruby-gems
COPY Gemfile* /app/
RUN bundle config build.nokogiri --use-system-libraries \
&& bundle install -j4
FROM ruby-base
WORKDIR /app
ARG RAILS_ENV
ARG RAILS_MASTER_KEY
ARG DB_USER
ARG DB_PASSWORD
ARG DB_HOST
ARG DB_PORT
RUN apt-get install -y \
curl \
gnupg2 \
&& echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list \
&& curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - \
&& apt-get update -y && apt-get install -y \
tzdata \
google-cloud-sdk \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /opt/yarn* /opt/yarn/
RUN ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
&& ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg
COPY --from=build-node-modules /app/node_modules node_modules/
COPY --from=build-ruby-gems /app/.bundle .bundle/
COPY --from=build-ruby-gems /app/vendor vendor/
VOLUME /app/node_modules /app/.bundle /app/vendor
COPY . /app
CMD bin/rails server -b 0.0.0.0 -p ${PORT}
下記の内容で docker-compose.yml
を作成します。
version: '3'
services:
mysql:
image: mariadb:10.7
volumes:
- ./docker/mysql/volumes/data:/var/lib/mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
MYSQL_ROOT_PASSWORD: ''
command:
- mysqld
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_bin
app:
build:
context: .
ports:
- 58000:8000
volumes:
- ./:/app:cached
depends_on:
- mysql
command: ["./scripts/wait-for-db.sh", "mysql", "bin/rails", "server", "-b", "0.0.0.0", "-p", "8000"]
scripts/
ディレクトリを作成し下記の内容で scripts/wait-for-db.sh
を作成します。
#!/bin/sh
# wait-for-db.sh
set -e
host="$1"
shift
until mysql -h "$host" -u root; do
>&2 echo "MySQL is unavailable - sleeping"
sleep 1
done
>&2 echo "MySQL is up - executing command"
exec "$@"
scripts/wait-for-db.sh
にパーミッションを付与しておきます。
% chmod a+x scripts/wait-for-db.sh
config/database.yml
を編集します。
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
- username: root
- password:
+ username: <%= ENV.fetch("DB_USER") { "root" } %>
+ password: <%= ENV.fetch("DB_PASSWORD") { "" } %>
+ host: <%= ENV.fetch("DB_HOST") { "mysql" } %>
+ port: <%= ENV.fetch("DB_PORT") { "3306" } %>
production:
<<: *default
- database: rails7_webpack_sample_production
- username: rails7_webpack_sample
- password: <%= ENV["RAILS7_WEBPACK_SAMPLE_DATABASE_PASSWORD"] %>
+ database: rails7_webpack_sample
Docker イメージをビルドします。
% docker compose build
データベース作成タスクを実行します。
% docker compose run --rm app bundle exec rails db:create
これで開発環境は完成です。開発サーバーを起動して動作確認してみましょう。
% docker compose up
下記のログが表示されたらブラウザで http://localhost:58000 にアクセスします。
app_1 | * Listening on http://0.0.0.0:8000
Rails のロゴが表示されたら成功です。
次に Webpack を使って JS をバンドルしてみましょう。
最初に確認のためのルーティングを追加します。config/routes.rb
を編集します。
Rails.application.routes.draw do
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Defines the root path route ("/")
- # root "articles#index"
+ root "articles#index"
end
下記の内容で app/controllers/articles_controller.rb
を作成します。
class ArticlesController < ApplicationController
layout "application"
def index
end
end
下記の内容で app/views/articles/index.html.erb
を作成します。
<h2>Articles</h2>
Procfile.dev
を編集します。
-web: bin/rails server -p 3000
+web: rm -f ./tmp/pids/server.pid && bin/rails server -b 0.0.0.0 -p 8000
js: yarn build --watch
docker-compose.yml
を編集します。
depends_on:
- mysql
- command: ["./scripts/wait-for-db.sh", "mysql", "bin/rails", "server", "-b", "0.0.0.0", "-p", "8000"]
+ command: ["./scripts/wait-for-db.sh", "mysql", "bin/dev"]
package.json
にビルドコマンドを追加します。
"dependencies": {
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1"
+ },
+ "scripts": {
+ "build": "webpack"
}
}
カスタム JavaScript ファイルとしてapp/javascript/hello-world.js
を作成します。
console.log("Hello World!")
エントリーポイントとなる app/javascript/application.js
で hello-world.js
をインポートします。
// Entry point for the build script in your package.json
+import "./hello-world"
Docker イメージをビルドし直して再度開発サーバーを起動します。
% docker compose down
% docker compose build
% docker compose up
ブラウザで http://localhost:58000 にアクセスします。
開発者ツールから JavaScript コンソールを開き Hello World!
が表示されていれば成功です。
今回使用したサンプルコードは下記のリポジトリにあります。
以上です。
この記事では JS のバンドラーとして webpack を使って Rails 7 を構成する方法を説明しました。
コメントを送る
コメントはブログオーナーのみ閲覧できます