タイトル通り、KombuというRuby on Railsでjavascriptで描画するcomponentを指定してrenderできるgemをリリースしました💎✨
(コンポーネント・レンダラブルを略してコンブ です)
github.com
モチベーション
Ruby on Railsを利用してサービスが成長してくるとVue.jsといったフロントエンドライブラリを利用することになると思いますが、
これがだんだん成長してくるとRailsのViewとフロントエンドフレームワークがどんどん密結合になっていき、
見通しが悪くなったり適切な境界を持たないことによるE2Eテストの肥大化及び明示的な検証が困難といった課題が出てくるなぁと思っていたので、
以下の記事に書いたようなControllerから直接ComponentをrenederすることでRailsのView層を隠蔽し一定の境界を手軽に作れるのでは?という感じで作りました。
madogiwa0124.hatenablog.com
似たようなライブラリだと以下のようなものがありますが、React-Railsの場合はReactを採用してないと採用できないのとInertia.js Rails Adapterはinertia.jsを導入しないと採用できず境界を分けたいだけのニーズではtoo muchかなと思い作成に至った次第です。(Vue.jsでの使用を主に想定してします)
使い方
使い方は割と簡単で以下をGemfileに追加 + bundle install
して
gem "kombu"
以下の通りに自身のアプリケーションに合わせて、jsからmountする要素のid、css/jsの読み込み用のタグの生成ロジック、隠蔽するview templateを設定して
Rails.application.configure do
NOTE
NOTE
config.kombu.javascript_entry_tag_proc = -> { helpers.javascript_pack_tag(@entry, defer: true) }
NOTE
config.kombu.stylesheet_entry_tag_proc = -> { helpers.stylesheet_pack_tag(@entry) }
NOTE
end
任意のControllerでKombu::Renderable
をincludeするとkombu_render_component
を使って任意のComponentを含んだhtmlタグをrenderすることが出来ます。renderする際にViewを必要としないので、layouts以外のViewファイルを削除することが可能になり、フロントエンドとサーバーサイドの境界を作ることが出来ます。
class ArticlesController < ApplicationController
include Kombu::Renderable
def index
@title = "Articles"
@articles = [{id: 1, title: "artile1", body: "body1"}, {id: 2, title: "artile2", body: "body2"}]
kombu_render_component("article-index-page", attributes: {title: @title, ":articles": @articles.to_json})
NOTE
end
end
またkombu_render_component
に渡された値を明示的に検証できるRSpecのmatcherを用意しているのでrequest specでサーバーサイドから渡す値を明示的に検証することが出来ます🙆♂️
describe "GET /articles", type: :request do
before { get articles_path }
it "Specific arguments must be passed to kombu_render_component." do
title = "Articles"
articles = [{id: 1, title: "artile1", body: "body1"}, {id: 2, title: "artile2", body: "body2"}]
expect(controller).to kombu_component_rendered("article-index-page", attributes: {title: title, ":articles": articles.to_json})
end
end
仕組み
基本的にはkombu_component_rendered
で指定した名称とattiributesを持つタグとjavascript_entry_tag_proc
、stylesheet_entry_tag_procで生成したタグを
config.kombu.default_entry_view_template`で指定したtemplateに埋め込んで返却しているだけです🧑🏭
詳しくはこちらの該当コードを参照してください。
github.com
おわりに
実際に自分の個人サービスで利用してるのですがapp/views
配下がlayouts
以外消せてスッキリでした👍