Author: 水卜
Author: 水卜
DockerでVue on Rails
Vueの双方向データバインディングやコンポーネントベースのフロント開発に慣れると、Rails + jQueryでは満足できない体になる。
Webpackerじゃなくてwebpackでよくねみたいな意見があるが、本記事では折角なのでWebpackerでやっていく。
環境構築
webコンテナに渡すGemfileとGemfile.lockを作成。
$touch Gemfile Gemfile.lock
Gemfileの中身に以下を記述。lockは空でいい。
source 'https://rubygems.org'
gem 'rails', '~>5'
docker-compose.ymlとDockerfileはそれぞれこんな感じに。
- docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7.19
environment:
- MYSQL_ROOT_PASSWORD=root
ports:
- "3307:3306"
volumes:
- ./tmp/db:/var/lib/mysql
webpacker:
build: .
command: bundle exec bin/webpack-dev-server
volumes:
- .:/myapp
ports:
- "3035:3035"
web:
build: .
environment:
RAILS_ENV: development
command: bash -c "bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
- bundle-data:/usr/local/bundle
ports:
- "3000:3000"
depends_on:
- db
- webpacker
volumes:
bundle-data:
- Dockerfile
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
&& apt-get install -y nodejs
RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && apt-get install -y yarn
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
CMD ["rails", "server", "-b", "0.0.0.0"]
下記コマンドを実行する。
docker-compose run web rails new . --force --database=mysql --webpack=vue --skip-coffee
sed -i ".bak" -e "s/host: localhost/host: webpacker/g" config/webpacker.yml
docker-compose build
docker-compose run web rails db:create
docker-compose up
自分がやった時は以下のように怒られた。rails newで–webpack=vueを指定するとこの辺はうまくやってくれるのかと思っていた。
webpacker_1 | internal/modules/cjs/loader.js:584
webpacker_1 | throw err;
webpacker_1 | ^
webpacker_1 |
webpacker_1 | Error: Cannot find module 'webpack'
webpacker:install系のコマンドを打つとモジュールがインストールされる。
docker-compose run web rails webpacker:install
docker-compose run web rails webpacker:install:vue
docker-compose build
docker-compose up
webpackのビルドが終わったよー的なログが出てからlocalhost:3000にアクセスするとyayが見れる。
Vueの画面を表示するまで
app/javascript/app.vue
を見るとこんな感じになっている。
<template>
<div id="app">
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data: function () {
return {
message: "Hello Vue!"
}
}
}
</script>
<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>
これを表示するために以下のようにファイルを変更していく。
config/routes.rb
Rails.application.routes.draw do
root to: 'home#index'
end
app/controllers/home_controller.rb
class HomeController < ApplicationController
def index
end
end
app/views/home/index.html.erb
<%= javascript_pack_tag 'hello_vue' %>
これでlocalhost:3000を見に行くとHello vueになっているはず。
ActiveRecordが使える分nuxtよりrails+vue構成のほうが便利かもしれない…
TypeScript導入
折角なので流行のTypeScriptでvueを書いていく。
$ docker-compose run web rails webpacker:install:typescript
app/javascript/packs/hello_vue.jsをhello_vue.tsにリネーム。
app/javascript/app.vueのscriptタグにtsを指定。
app/javascript/app.vue
(略)
<script lang="ts">
(略)
VSCodeだとこの時点でエラーが出るので、ts-loaderがvueファイルも見るようにする
config/webpack/loaders/typescript.js
module.exports = {
test: /\.(ts|tsx)?(\.erb)?$/,
use: [
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
}
]
}
Vueの型定義ファイルを追加して完了。
app/javascript/types/vue.d.ts
declare module "*.vue" {
import Vue from 'vue'
export default Vue
}