これはなに
Sinatra で echo サーバを、 Vue.js でフロントを構築しようというチュートリアルです。
この記事では Sinatra, Vue.js どちらも触れて、 hello world
を表示するところまで行います。
「ウェブアプリケーションを作りたいけど何からやっていいかわからない」、「Vue.js やりたいけど、フロントエンド周りがよくわからない」という方向けの記事になります。
入門にしては内容が多めですが、どれも Web開発をするためには便利なツールなので一度自分の手で実行してみることを推奨します。
全てのコードはこちらのリポジトリにあります。
https://github.com/Asuforce/sinatra_with_vue
取り扱うソフトウェア
雑に役割を書いてますが、ここで理解できなくても大丈夫です。
チュートリアルを進めながら学んでいきましょう。わからない部分はまずはリンクしてある公式サイトを見ることがオススメです。
全て 18/3/18 時点の最新のバージョン、シンタックスになるように努力しました。(改善点大歓迎です。
-
Sinatra
- Webアプリケーションフレームワーク
- さくっとサーバーサイドが作れます
-
Bundler
- gemマネージャー
- gem を管理できます
-
Slim
- テンプレート言語
- 楽に html が書けるオススメの gem です
-
RSpec
- サーバーサイドのテストツール
- Webアプリケーションの振る舞いをテストします
-
npm
- jsパッケージマネージャー
- js のライブラリを管理できます
-
Webpack
- jsバンドラー
- js ファイルを任意の設定でまとめてくれます
-
Vue.js
- jsプログレッシブフレームワーク
- UI を構築するためのフロントエンドライブラリです
事前準備
以下のソフトウェアを取り扱うので予めインストールしておいてください。バージョンは 18/3/18 のものになります。
あと簡単な Linux コマンドを多用するので、お好きなターミナルを起動しておいてください。
Sinatra でサーバサイドを作る
init
git 管理したい人は、ここで git init
しておくと捗ります。
mkdir myapp
cd myapp
bundle init
echo gem \"sinatra\" >> Gemfile
bundle install -j4 --path vendor/bundle
touch app.rb
hello, world
require "sinatra/base"
class MyApp < Sinatra::Base
get "/" do
'hello, world!'
end
run! if app_file == $0 # ファイルを読み込むとサーバを実行する
end
bundle exec ruby app.rb
http://localhost:4567 にアクセスして Hello world!
が見えたら正常です。
Mac の場合以下のコマンドが便利です
open http://localhost:4567
git で管理している人は.bundle
, venodr
を .gitignore
に追加しましょう。
echo '/.bundle/\n/vendor/' > .gitignore
開発効率を向上させる
ここまでのアプリケーションでローカルサーバを立ち上げてから、 hello, world
を変えて再アクセスしてみましょう。レスポンスが hello, world
が変更されない筈です。現状はサーバの設定がリロードを実行しないと読み込まれません。
これでは効率が悪いので以下の設定で改善します。
sinatra-contrib
を Gemfile
に追加します。
sinatra-contrib
には他にも便利なライブラリがあるので下記を参考にしてみると発見があると思います。
echo gem \'sinatra-contrib\' >> Gemfile
bundle install
app.rb
に以下を書き加えます。
require "sinatra"
+require 'sinatra/reloader'
class MyApp < Sinatra::Application
+ configure :development do
+ register Sinatra::Reloader
+ end
+
get "/" do
これでローカルサーバを起動しながら、ガンガン変更ができるようになります。
Test を書く
簡単なアプリケーションができたので、テストも作成してみましょう。
ref: http://recipes.sinatrarb.com/p/testing/rspec
RSpec を使います。下記を Gemfile
に追加します
gem "sinatra"
gem 'sinatra-contrib'
+
+group :test do
+ gem 'rspec'
+ gem 'rack-test'
+end
bundle install
して rspec --init
を実行します。
bundle install
bundle exec rspec --init
spec/spec_helper.rb
を下記のように書きましょう。
require 'rack/test'
require 'rspec'
ENV['RACK_ENV'] = 'test'
require File.expand_path '../../app.rb', __FILE__
module RSpecMixin
include Rack::Test::Methods
def app
MyApp
end
end
RSpec.configure { |c| c.include RSpecMixin }
spec/app_spec.rb
を作成しテストを記述します。テストの内容はページのレスポンスと body の内容を確認するものです。
touch spec/app_spec.rb
describe "My Sinatra Application" do
before :all do
get '/'
end
it "should allow accessing the home page" do
expect(last_response).to be_ok
end
it "should discribe message" do
expect(last_response.body).to eq('hello, world!')
end
end
テストが書けたら以下を実行して、実際に RSpec を実行してみましょう。
緑色の文字で 2 example, 0 failures
と出たら成功です。
bundle exec rspec
View を表示する
Slim というテンプレートエンジンを使います。Ruby には標準ライブラリの ERB を用いる事が多いですが、今回はよりシンプルに記述できる Slim を使って View を作成します。
Slim の記法は以下の記事が大変参考になります。
マークアッパー的 Slim 入門21の手引き
echo gem \"slim\" >> Gemfile
bundle install
mkdir views
touch views/index.slim
doctype html
html
head
meta charset="UTF-8"
title MyApp
body
div id="app"
h1 hello, world
同じファイルを html で出力してみましょう。
bundle exec slimrb -p views/index.slim | cat
このような出力結果が得られます。Slim の方がスッキリした印象があると思います。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>MyApp</title>
</head>
<body>
<div id="app">
<h1>
hello, world
</h1>
</div>
</body>
</html>
アプリケーションのコードを変更して View ファイルを表示してみましょう。
require "sinatra/reloader"
+require "slim"
class MyApp < Sinatra::Base
configure :development do
register Sinatra::Reloader
end
get "/" do
- 'hello, world!'
+ slim :index
end
H1 タグで大きく表示されるようになっていたら成功です。
データの受け渡し
ここまでで静的なページを作ることができました。
次はアプリケーションからのパラメータを表示する例です。
get "/" do
+ @message = 'This is MyApp'
slim :index
end
body
div id="app"
- h1 hello, world
+ h1 = @message
ブラウザをリロードして This is MyApp
と表示されたら成功です。
このままだとテストが失敗してしまうので、メッセージの内容を正しく書き直してテストをパスするようにします。
it "should discribe message" do
- expect(last_response.body).to eq('hello, world!')
+ expect(last_response.body).to include('This is MyApp')
end
再度テストを実行してパスすることを確認してください。
フロントエンドの作成
Vue.js の導入
予め のインストールをお願いします。
Node.js がインストールできたら以下を実行してください。package.json
が作成されます。
# package.json を初期化します
npm init -y
# i = install
# -D = devDependencies に追加
npm i -D webpack webpack-cli
# Vue.js のインストール
npm i vue
./node_modules
にモジュールがインストールされます。
このディレクトリは ignore します。
echo /node_modules/ >> .gitignore
今回は以下の設定が package.json
にあれば十分です。(特にデフォルトから編集する必要はありません。が以下をベースに話を進めます。
{
"dependencies": {
"npm": "^5.7.1",
"vue": "^2.5.16"
},
"devDependencies": {
"webpack": "^4.1.1",
"webpack-cli": "^2.0.12"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
}
webpack の準備
ref: 最新版で学ぶwebpack 4入門 – JS開発のモジュールバンドラ
Vue.js の導入を行なった際に webpack も導入しました。
これは高度な Web アプリケーションの構築のためのモジュールバンドラーです。js, css の minify をビルド時に実行することも可能です。
参考記事がとてもわかりやすいので、併せてご覧ください。
早速、webpack の設定を行いましょう。
touch webpack.config.js
以下の設定で ok です。
entry
はデフォルトの src/index.js
を使うので書きません。output
は Sinatra が js ファイルを読み込む public
以下に作ります。
const path = require('path')
module.exports = {
output: {
path: path.join(__dirname, 'public', 'js'),
filename: 'main.js'
},
resolve: {
alias: {
'vue': 'vue/dist/vue.common.js'
}
}
};
ファイルとディレクトリなども作成しておきましょう。
mkdir src
touch src/index.js
mkdir public
touch public/.gitignore
Vue.js を記述する
早速、 Vue.js を使ってデータを表示していきましょう。
index.slim
を以下のように設定します。
v-text
はテキストコンテンツを表示するためのディレクティブです。よく {{message}}
このような mustache 記法が使われる事が多いですが、DOM が構成された後に画面に描画されてしまうのを防ぐために v-text
を使っています。
この問題は DOM が描画される前に js ファイルが読み込まれると発生します。footer で読み込んでいるのは header だと先述の問題が発生しやすいためです。知見がある方はこの現象の回避方法をご教授いただければと思います。
body
div id="app"
- h1 = @message
+ h1 v-text="message"
+ footer
+ script type="text/javascript" src="/js/main.js" charset="utf-8"
js ファイルはこのように記述します
Vue = require('vue')
new Vue({
el: '#app',
data: {
message: 'Hello world from Vue.js'
},
});
ここまでできたら build をしましょう。npm script を活用します。
--mode
は Webpack4 からの機能になり、development
, production
が選べます。
"webpack-cli": "^2.0.11"
},
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "build": "webpack --mode development"
}
以下のコマンドを実行して、ビルドを行います。
npm run build
build が終わったら public/js/main.js
を確認してみましょう。Vue.js 本体を含む諸々が1個のファイルになってるのがわかります。
確認できたらローカルサーバを立ち上げて確認しましょう。画面に Hello world from Vue.js
と表示されたら成功です。
この変更によって再度テストが落ちるようになっています。画面の描画は Vue.js が担うようになったので RSpec のテストの範疇を超えました。実際はフロントエンドテストフレームワークを使ってテストをするのが望ましいですが、今回は割愛させていただきます。
対象の部分を削除して、テストを通します。
it "should allow accessing the home page" do
expect(last_response).to be_ok
end
-
- it "should discribe message" do
- expect(last_response.body).to include('This is MyApp')
- end
end
まとめ
ここまでの作業で、Webアプリケーションの仕組みに触れながら、最新の環境を作成できるようになりました。
ここで作ったアプリケーションを使って自分なりの工夫をしてみるとより理解が深まると思います。