RailsでSPAを実装する方法はいくつかある。
- Webpacker
- Railsとwebpack
- Rails(APIサーバー)とNode.js(フロントエンド)
今回はRailsとwebpackを使った方法を紹介する。 Railsとwebpackを利用すれば、フロントエンドとサーバーサイドを疎結合に保ちつつ、コンパクトなコードベースでSPA開発ができる。 仕組みとしては、リクエストをRailsが受け取り、Viewを表示してから、webpackでコンパイルしたJSを使ってコンテンツを表示する。 仕組みはWebpackerも同じだが、webpackがgemに依存しなくてよい。
今回は開発環境について説明する。 コードはこちらに公開する。
.
├── app
│ ├── controllers
│ │ └── apps_controller.rb
│ ├── helpers
│ │ └── application_helper.rb
│ └── views
│ └── apps
│ └── show.html.erb
├── config
│ └── routes.rb
├── frontend
│ ├── config
│ │ └── webpack.config.js
│ └── src
│ └── apps.js
├── docker-compose.yml
├── Dockerfile
└── package.json
開発環境はdocker-composeを使う。 railsとwebpack-dev-serverとdbのコンテナを用意する。
version: "3"
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
app:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- db
webpack:
image: node:12.14
command: bash -c "yarn install && yarn start"
depends_on:
- app
working_dir: "/app"
volumes:
- .:/app
ports:
- "3500:3500"
FROM ruby:2.6
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
リクエストはRailsが受け付け、空のViewを表示する。 Viewからwebpack-dev-serverにリクエストを送り、JSでコンテンツを表示する。
Rails.application.routes.draw do
root to: 'apps#show'
get '/*all' => 'apps#show'
end
class AppsController < ApplicationController
def show
end
end
<div id="app"></div>
<%= javascript_include_tag webpack_asset_path('apps.js') %>
module ApplicationHelper
def webpack_asset_path(path)
"http://localhost:3500/#{path}"
end
end
{
"name": "rails-spa",
"private": true,
"scripts": {
"start": "webpack-dev-server --hot --inline --color --progress --host 0.0.0.0 --config frontend/config/webpack.config.js"
},
"dependencies": {},
"devDependencies": {
"webpack": "^4.41.4",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.1"
}
}
module.exports = {
entry: { apps: "./frontend/src/apps.js" },
output: {
filename: "[name].js",
publicPath: "http://localhost:3500/"
},
mode: "development",
devServer: {
public: "127.0.0.1:3500",
publicPath: "/",
compress: true,
port: 3500,
progress: true,
hot: true,
headers: {
"Access-Control-Allow-Origin": "*"
},
sockPort: 3500
}
};
const component = () => {
const element = document.getElementById("app");
element.innerHTML = "Hello webpack!!";
return element;
};
document.body.appendChild(component());
今回はRailsとwebpackを使ったSPAの開発環境の作り方を紹介した。