Rails Assets Precompile でコンパイルしたファイルをクライアント側で動的に読込みたいときの対応

ややこしいし、滅多にない状況だけど忘れないために。
JavaScriptのライブラリなどが、RailsのAssets PrecompileでコンパイルしたJavaScriptまたはCSSなどを動的に読込む(requireJSなどで)必要がある場合の対応。

具体的なパターンとしては、

  • ライブラリ本体が実行時に特定のAssetsファイルをincludeするとき
  • ライブラリ本体が相対パスで特定のAssetsファイルをincludeするとき
    上記の場合、Precompileされたファイルにはanyload-avnov92ns2fd5db7e7290baa07400kcinqhb.cssのようにasset digest値が付与されるため、anyload.cssを読込むと確実に404が返されます。

[shell]
├── app(precompiled)
│ ├── assets
│ ├── javascrips
│ ├── stylesheets
├──lib(precompiled)
│ ├── assets
│ ├── javascrips
│ ├── stylesheets
│ ├── vendor(not precompiled)
│ ├── components
│ ├── public
[/shell]

例えばvendor配下のJavaScriptのライブラリはPrecompile対象ではなく、ライブラリが動的に読込むファイルはAssets Precompileの対象(appまたはlib配下)となる状況でした。

おそらくRailsのAssets Precompileを想定してないJavaScriptライブラリやgemで提供されているJavaScriptライブラリにはありこういう状況があり得そう。

読込まれるJavaScript,cssをPrecompileしなけりゃいいけど、ライブラリによっては回避できないこともありそうなのでその場合の考えられるの回避方法が

  1. ライブラリの設定やスクリプトファイルをForkして変更する
  2. config.assets.digest = false
  3. RailsのPrecompile対象から外すように設定変更し、読込まれるファイルをpublicに設置
  4. config.assets.digest = false にして、digestを付与しないでコンパイル
  5. RailsのAssets Precompileを使用しないで自前でコンパイル

という選択肢を検討しましたが、便利なgemを使って解決できました。

ここにまとまってますね。

Comments