search
LoginSignup
2
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

Organization

Sprocketsの生きる道 in JavaScript

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;

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2
Help us understand the problem. What are the problem?