こんにちは。@river_okaです。
JavaScriptファイルをプロジェクトで一つにまとめると、肥大化してどこをいじったら良いかわからないみたいな状態になっちゃいますよね。
そういうときはページ毎に.jsファイルを分けたりします。
今回はwebpacker を使って entry pointをページ毎に分けていきたいと思います。
サンプルは下記に雑にあげております。
https://github.com/kawoka/webpacker_entry_point_example
Webpackerの導入
railsのプロジェクトから作る場合は下記
rails new myapp — webpack
既存のプロジェクトに追加する場合は下記でGemが入ります
# Gemfile
gem ‘webpacker’, ‘~> 3.5'
初期化
bundle exec rails webpacker:install
いろんなオプションを追加したりすると VueやReactの初期化までしてくれたりします。
webpacker.yml の設定
default: &default
source_path: frontend
source_path を frontendに変えました。
この辺はお好みで設定してください。
routeの作成
# route.rb
resources :hoge, only: %i(index)
resources :fuga, only: %i(index)
hoge#index と fuga#indexを作りました。
このactionとJavaScriptファイルをdispatchしていきます。
.jsファイルの作成
action毎にjsファイルを作成していきます。
今回は上で作成した2ページに対してそれぞれjsファイルを作成します。
frontend/packs/hoge/index.js
alert('hoge#indexのjavascriptです')
frontend/packs/fuga/index.js
alert(‘fuga#indexのjavascriptです’)
jsとactionをdispachする
いよいよ繋げましょう
application_helperに下記メソッドを追記します
# app/helpers/application_helper.rb
def javascript_path
"#{controller_path}/#{action_name}.js"
end
そしてlayoutsのjavascript_pack_tagを下記のように書きます
# app/views/layouts/application.html.erb
<%= javascript_pack_tag javascript_path %>
</body>
</html>
はい終わりです。
それぞれのページにアクセスしてalertが出ました。簡単ですね。
jsが見つからない場合はdefault.jsにフォールバックさせる
jsが必要ないページもあるかと思います。
そのようなページにアクセスすると…
jsがないよって怒られます…
なのでフォールバックを作りましょう
フォールバック用のdefault.jsを作成します
# frontend/packs/default.js
alert('defaultのjavascriptです')
そしてhelperを下記のように書き換えます
def javascript_path
path = "#{controller_path}/#{action_name}.js" # 見つからない場合はdefault.jsを返す
return "default.js" unless javascript_file_exist?(path)
path
enddef javascript_file_exist?(path)
manifest = File.open('public/packs/manifest.json') do |file|
JSON.load(file)
end
manifest.key?(path)
end
これでjsがないページもdefaultのjsがロードされるようになりました。
細かなパフォーマンスの話をすると、File.openを毎回行うのは重いので、cacheをするなどすると丁寧かと思います。
そんな感じで分けると影響範囲が明確になるので、ページ固有の実装は安心して実装しやすくなりました。
そんなこんなでジラフではエンジニアさんを大募集中です。
よければ遊びに来てください!!!