Help us understand the problem. What is going on with this article?

Sprocketsの生きる道 in JavaScript

More than 3 years have passed since last update.

RailsプロジェクトのJavaScriptをWebpackerで書いていたのですが、Sprocketsの方がいい場面、というのが出てきました。

プロジェクトの状況

もともとRails 4から続くプロジェクトで、JavaScriptもCSSもSprocketsに載せていました。そして、JavaScriptのES6対応や依存関係管理の都合もあって、JavaScriptのほうはWebpackerに載せ替えていきました。一方で、CSSはSCSSで必要十分だったので、Sprockets管理のままで運用を続けています。

別プロセスのコスト

その中で、Rails側から値を取ってくる必要のあるimage_path参考)や、Railsにある定数をJavaScriptにも持ち込みたいような場合、.js.erbとしてERBでJavaScriptを生成する、という方法があります。

もちろん、Webpackerでも.js.erbを使う方法があって、その名もrails-erb-loaderGitHub)というローダーを使えば、読み込むこと自体は可能です。

ただ、rails-erb-loaderは、1ファイルの処理につき1つRailsのプロセスを立ち上げてしまうために、.js.erbファイルが増えれば加速度的に処理時間がかかるようになってしまいます。

Rubyの道はRuby

ここで、Sprocketsに視点を戻してみましょう。もともとSprocketsはRubyの枠内で処理を行うので、ERBが来ても別プロセスを立てるようなコストは発生せず、通常のファイルと大差ないプロセスで処理ができます。

ということで、もともとCSSのためにSprocketsの運用を続けていたこともあるので、ERB処理の必要なものだけSprocketsで書いて、Webpackerからはそれを参照するように書くのがいいのではないか、と思い始めてきました。

// Sprocketsで書くERB
<%
imgs = {}
Dir.chdir("#{Rails.root}/app/assets/images/") do
  imgs = Dir["**/*"].inject({}) do |h,f|
    h.merge!(f => image_path(f)) unless Dir.exist? f
    h
  end
end
%>
window.fromRuby = {};

window.fromRuby.imagePath = function(name){
  return <%= imgs.to_json %>[name];
}

// Webpacker側に書くJavaScript
// 依存性の管理が混乱するので、直接fromRubyを呼ぶ箇所は、減らした方がいい
// このファイルをimportして使う

const imagePath = window.fromRuby.imagePath;
export default imagePath;
jkr_2255
qiitadon
Qiitadon(β)から生まれた Qiita ユーザー・コミュニティです。
https://qiitadon.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away