Skip to content

Assets resolution fails when initializers are run in different order #2433

@jan-evermood

Description

@jan-evermood

We have a Rails application with view_component and sprockets, and after upgrading to VC 4.0, tests fail only in CI, which has eager_load set to true. One component uses image_tag and fails with the asset not being found:

     Sprockets::Rails::Helper::AssetNotFound:
       The asset "xyz.svg" is not present in the asset pipeline.

This does not happen when running the same spec without eager loading.

This is caused by resolve_assets_with being nil, but only when eager loading:

$ CI=1 rspec ...

    246:       end
    247:
    248:       # List of resolvers in `config.assets.resolve_with` order.
    249:       def asset_resolver_strategies
    250:         @asset_resolver_strategies ||= begin
 => 251:           binding.irb
    252:           Array(resolve_assets_with).map do |name|
    253:             HelperAssetResolvers[name].new(self)
    254:           end
    255:         end
    256:       end

3.4.5 :001 > resolve_assets_with
 => nil
3.4.5 :002 > ::Rails.application.config.assets.resolve_with
 => [:manifest, :environment]

Without eager loading:

    246:       end
    247:
    248:       # List of resolvers in `config.assets.resolve_with` order.
    249:       def asset_resolver_strategies
    250:         @asset_resolver_strategies ||= begin
 => 251:           binding.irb
    252:           Array(resolve_assets_with).map do |name|
    253:             HelperAssetResolvers[name].new(self)
    254:           end
    255:         end
    256:       end

3.4.5 :001 > resolve_assets_with
 => [:manifest, :environment]
3.4.5 :002 > ::Rails.application.config.assets.resolve_with
 => [:manifest, :environment]

I've traced this back to the initializers from sprockets-rails and view_component.

I added print statements to both and got different results when eager-loading and when not:

With eager loading:

$ CI=1 rspec ./spec/.../spec.rb:38
VC: copy relevant config to VC context
sprockets-rails: set config.assets.resolve_with
Run options: (..)

Randomized with seed 1624

Spec:

From: .rvm/gems/ruby-3.4.5/gems/sprockets-rails-3.5.2/lib/sprockets/rails/helper.rb @ line 251 :

    246:       end
    247:
    248:       # List of resolvers in `config.assets.resolve_with` order.
    249:       def asset_resolver_strategies
    250:         @asset_resolver_strategies ||= begin
 => 251:           binding.irb
    252:           Array(resolve_assets_with).map do |name|
    253:             HelperAssetResolvers[name].new(self)
    254:           end
    255:         end
    256:       end

3.4.5 :001 > resolve_assets_with
 => nil
3.4.5 :002 >

    spec (FAILED - 1)

Failures:

  1) spec
     Failure/Error: image_tag(icon_path)

     Sprockets::Rails::Helper::AssetNotFound:
       The asset "xyz.svg" is not present in the asset pipeline.

Without eager loading:

$ rspec ./spec/.../spec.rb:38
sprockets-rails: set config.assets.resolve_with
Run options: (..)

Randomized with seed 20911

Spec:
VC: copy relevant config to VC context

From: .rvm/gems/ruby-3.4.5/gems/sprockets-rails-3.5.2/lib/sprockets/rails/helper.rb @ line 251 :

    246:       end
    247:
    248:       # List of resolvers in `config.assets.resolve_with` order.
    249:       def asset_resolver_strategies
    250:         @asset_resolver_strategies ||= begin
 => 251:           binding.irb
    252:           Array(resolve_assets_with).map do |name|
    253:             HelperAssetResolvers[name].new(self)
    254:           end
    255:         end
    256:       end

3.4.5 :001 > resolve_assets_with
 => [:manifest, :environment]

The view_component initializer is run before the initializer from sprockets-rails can set up the config options.

Steps to reproduce

Working on that. It is a bit challenging to reproduce in isolation/a demo app.

Expected behavior

view_component needs to run its initializer after sprockets-rails to delegate/get the values later.

Actual behavior

The view_component initializer can run before sprockets-rails and will assign nil values to all options. This will break using asset methods in view components.

Backtrace:

System configuration

Rails version: 8.0.2

Ruby version: 3.4.5

Gem version: 4.0.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions