komponent icon indicating copy to clipboard operation
komponent copied to clipboard

Zeitwerk compatibility

Open aldhsu opened this issue 5 years ago • 12 comments

Are there any tips for making components compatible with Zeitwerks name expectations?

Related to this issue https://github.com/komposable/komponent/issues/117

The error I'm seeing is like this:

ActionView::Template::Error:
       expected file /Users/allen.hsu/Code/komponent-namespace/frontend/components/users/avatar/users_avatar_component.rb to define constant Users::Avatar::UsersAvatarComponent, but didn't

This dependent on test ordering I don't actually see it in development. However it is reproducible by loading the view twice in the test.

I have considered:

  1. Using a custom inflector - you can't inflect the paths leading up to the component that turns into the module path
  2. Monkey patch Komponent until something lands for #117
  • this requires renaming all the modules as well
  1. Don't autoload the components
  • changes to a components rb file requires server restarts
  • I am investigating not autoloading or eagerloading in tests

aldhsu avatar Sep 30 '19 06:09 aldhsu

I have settled on disabling autoloading for frontend in tests for now.

aldhsu avatar Oct 01 '19 05:10 aldhsu

Actually tried to deploy this but similar issues cropped up in production.

aldhsu avatar Oct 02 '19 07:10 aldhsu

I have same issues.

danieldocki avatar Oct 02 '19 15:10 danieldocki

Hi @aldhsu thanks for opening this issue. Actually we haven't been using Komponent in Rails 6 yet, so I'm not really informed to debug this.

I'd be happy to move on with #117 if it solves this issue at the same time.

We're welcoming any contribution :)

Spone avatar Oct 02 '19 15:10 Spone

Hi @aldhsu we have the same issue here on Rails 6 with Zeitwerks.

I start investigating on my side too.

And, I think the following should resolve the issue.

config.paths.add "frontend/components", eager_load: true, glob: "*".

Before change:

% abr zeitwerk:check 
Hold on, I am eager loading the application.
expected file frontend/components/alert/alert_component.rb to define constant Alert::AlertComponent

After:

% abr zeitwerk:check
Hold on, I am eager loading the application.
All is good!

I'll try it on production tomorrow. Let me know if you do some tries in your side.
Also I'm not sure if it's compatible with Rails < 6.0

nicolas-brousse avatar Nov 19 '19 23:11 nicolas-brousse

I just deployed and it seems to works 🎉

nicolas-brousse avatar Nov 19 '19 23:11 nicolas-brousse

Ok @nicolas-brousse I'll give it a go. Is that only in production?

aldhsu avatar Nov 19 '19 23:11 aldhsu

I've to check, but my coworker adds some issues on development too. Ruby part of component was loaded but didn't seems to reload code on changes. He adds to restart is server on component changes.

I'll try to do more test tomorrow.

nicolas-brousse avatar Nov 19 '19 23:11 nicolas-brousse

It seems to resolve the issue in development too, on our side.

nicolas-brousse avatar Nov 20 '19 13:11 nicolas-brousse

I have to double check, but this fix seems to resolve issue only for component without namespace unfortunately ...

nicolas-brousse avatar Nov 22 '19 22:11 nicolas-brousse

Zeitwerk release 2.3.0 added #collapse. Maybe it may help us.

https://github.com/fxn/zeitwerk#collapsing-directories

nicolas-brousse avatar Mar 03 '20 22:03 nicolas-brousse

Hi. Bit of a workaround, but this is working for me atm on Rails 6 with zeitwerk 2.4.0

module MyApp 
  class Application < Rails::Application
    config.i18n.load_path += Dir[config.root.join('frontend/components/**/*.*.yml')]
    config.paths.add 'frontend/components', eager_load: true, glob: '*'
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0

    overrides = Rails.root.join('frontend/components/komponent')
    Rails.autoloaders.main.ignore(overrides)
    config.to_prepare do
      Dir.glob("#{overrides}/**/*.rb").each do |override|
        load override
      end
    end

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
  end
end

GeoffTidey avatar Jul 31 '20 10:07 GeoffTidey