2020-01-04

opal-webpack-loaderでWebアプリを書く

昨日のつづきです。

昨日はdevelopmentモードで動かすことができました。今日はproductionで動かしたり、実用的なWebアプリを書くためのアレコレをしてみましょう。

gemを読み込む

productionで動かす前にgemをどうやって読み込むの?というのをやってみます。

まずはGemfileに使いたいgemを追加しましょう。

gem 'hyalite'
$ bundle install

さて、ここでapplication.rbrequire 'hyalite'すれば良いのですが、実はこれだけではgemを読み込むことはできません。

app_loarder.rbに次の一行を追加してください。

Opal.use_gem 'hyalite'

それでは、application.rbをhyaliteをつかって書き換えてみましょう。

require 'native'
require 'hyalite'

class ApplicationView
  include Hyalite::Component

  def render
    h1(nil, 'Hello, Hyalite!!')
  end
end

Hyalite.render(Hyalite.create_element(ApplicationView), $document[".content"])

ページに"Hello, Hyalite!!"って出たら勝ちです!

Sinatraを使うようにする

みんな大好きなSinatraでHTMLも動的に生成します。

動的に生成と言ってもここではあくまでSinatraをどうインテグレーションするのかという例を示すに留めて、動的な要素はみなさんの創造性にお任せすることにします。

最も簡単なSinatraのアプリケーションは以下のようなものでしょう。

require 'sinatra'
get '/frank-says' do
  'Put this in your pipe & smoke it!'
end

おっと、失礼しました。これではJavaScriptのコードを読み込むことができませんので、以下のようにerbをレンダリングするようにしましょう。

require 'sinatra'
get '/' do
  erb :index
end

index.htmlviewsディレクトリに異動して拡張子を.erbに変更します。(views/index.erb)

これで準備完了。Sinatraアプリを起動します。

$ ruby app.rb

productionで動かす

それではproductionで動かしてみましょう。Sinatra側は-eオプションを指定します。

$ ruby app.rb -e production

Webpackのdevelopmentサーバーを止めてしまうと、当然JavaScriptのファイルを読めなくなってエラーになります。 虚しくまっしろいページが表示されることでしょう。

JavaScriptのファイルをプリコンパイルするために以下のコマンドを実行します。

$ yarn run production_build

プリコンパイルに成功すると以下のようにファイルが生成されます。(cae2faf25ed9cfbc18b3というのはMD5ハッシュなのでビルドする毎に変わります。)

$ ls public/assets
application-cae2faf25ed9cfbc18b3.js  application-cae2faf25ed9cfbc18b3.js.gz  manifest.json

このハッシュ付きのファイルを読み込む必要があります。manifest.jsonの中にメタ情報が入っています。これをサーバーで読んでHTMLファイルの中に埋め込みます。安心してください、そのためのヘルパーはちゃんと用意されています。 app.rbを以下のように書き換えてください。

require 'bundler/setup'
Bundler.require(:default)

require 'sinatra'
require_relative 'owl_init'

include OpalWebpackLoader::ViewHelper

get '/' do
  erb :index
end

Sinatraアプリ側でもopal-webpack-loader gemを使えるようにして、ViewHelperクラスをインクルードします。これでビューでヘルパーを使えるようになりました。 次はviews/index.erbを次のよう書き換えましょう。

<!doctype html>
<html>
<body>
  <div class="content"></div>
  <%= owl_script_tag('application.js')%>
</body>
</html>

サーバーを再起動したら今度はちゃんと"Hello, Hyalite!!"と表示されるはずです。

developmentモードでもちゃんと動くことも確認しましょう。 ViewHelperが格モードで読み込むファイルを切り分けていることが分ります。