Sprocket Rails V4 の外部 gem のマニフェスト ファイルへのリンク
概要
Ruby 3、Rails 7+、および Sprockets V4 を使用していると、gem から CSS アセットをコンパイルするのに問題が発生します。
gem を (Rails エンジンとして) 作成しました。それには app/assets/stylesheets/my_gem にいくつかの .css アセットが含まれています (このディレクトリはメインの Rails アプリケーションではなく my_gem プロジェクト内にあることに注意してください)。 app/assets/config/my_gem_manifest.js ファイルには、必要な実際の .css ファイルが含まれています。
my_gem アセットをメインの Rails アプリケーションで使用できる唯一の方法は、Gem のパスを明示的に設定し、次のようにメインの Rail アプリケーションのロード パスに css ファイルを手動で追加することです。
(メインアプリ application.rb 上)
config.assets.paths << '/usr/local/bundle/gems/my_gem-0.1.7/app/assets/stylesheets/my_gem'
これを行うことで、実際にエラーなしで CSS を要求できますが、私の目標は、「my_gem」のマニフェスト ファイルのみを追加し、Sprockets で実際に gem の CSS アセットをコンパイルし、それをメインの Rails アプリケーションで利用できるようにすることです。
また、Gem のマニフェスト ファイルが存在するディレクトリを手動で追加しようとしたり、マニフェスト ファイルをメイン アプリのプリコンパイル リストに追加しようとしたりしましたが、次のように成功しませんでした。
config.assets.paths << '/usr/local/bundle/gems/my_gem-0.1.7/app/assets/config'
config.assets.precompile << "my_gem_manifest.js"
何日もこれと格闘中!助けていただければ幸いです。ありがとう。
解決策
設定:
bin/rails plugin new my_gem
# my_gem/lib/my_gem/railtie.rb
module MyGem
class Railtie < ::Rails::Railtie
def root
@root ||= Pathname.new(__dir__).parent.parent
end
initializer :my_gem_assets do |app|
# This is to be able to require your styles from main app application.css
# like this:
#
# /* =require my_gem/application.css */
#
app.config.assets.paths << root.join("app/assets/stylesheets")
# This is to be able to directly link your styles from your templates:
#
# <%= stylesheet_link_tag "my_gem/application.css" %>
#
# this path is relative to any `app.config.assets.paths`
app.config.assets.precompile << "my_gem/application.css"
end
end
end
マニフェストを使用する場合:
# my_gem/lib/my_gem/railtie.rb
module MyGem
class Railtie < ::Rails::Railtie
def root
@root ||= Pathname.new(__dir__).parent.parent
end
initializer :my_gem_assets do |app|
app.config.assets.paths << root.join("app/assets/stylesheets")
app.config.assets.paths << root.join("app/assets/config") # <-----------------------.
app.config.assets.precompile << "my_gem_manifest.js" # relative to asset path -'
end
end
end
// my_gem/app/assets/config/my_gem_manifest.js
//= link my_gem/application.css
https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://github.com/rails/sprockets#directives
設定:
bin/rails plugin new my_engine --mountable
Railtie とは異なり、Engine は多くのことを処理します。
# my_engine/lib/my_engine/engine.rb
module MyEngine
class Engine < ::Rails::Engine
isolate_namespace MyEngine
initializer :my_engine_assets do |app|
# This is automatically done by Rails::Engine
# app.config.assets.paths << root.join("app/assets/stylesheets")
# so you can just require files without extra config
#
# /* =require my_engine/application.css */
# If you want to link directly:
#
# <%= stylesheet_link_tag "my_engine/application.css" %>
#
# add that file to be precompiled
# app.config.assets.precompile << "my_engine/application.css"
#
# or use manifest
# ('app/assets/config' is automatically added to assets paths)
app.config.assets.precompile << "my_engine_manifest.js"
end
end
end
// my_engine/app/assets/config/my_engine_manifest.js
//= link_directory ../stylesheets/my_engine .css
これで、メイン アプリから gem/engine アセットを使用できるようになりました。
# app/views/layouts/application.html.erb
# we can do this because these files are in
# Rails.application.config.assets.paths and
# Rails.application.config.assets.precompile
<%= stylesheet_link_tag "my_gem/application.css" %>
<%= stylesheet_link_tag "my_engine/application.css" %>
または、メインアプリの application.css からファイルを要求することもできます。
/* app/assets/stylesheets/application.css */
/* in this case you don't have to precompile them
* =require my_gem/application.css
* =require my_engine/application.css
*/