feat(shell): choose the import map entry point and map; opt out of the auto-pin

Merged
MH
14d ago
+194-1

Summary

A host with several import maps can now give its docs their own entry point and map, and keep the docs-nav pin out of its shared map.

  • c.importmap_entry_point (default "application") and c.importmap (nil, an Importmap::Map, or a callable resolved on every render) feed DocsUI::Shell's javascript_importmap_tags through a new private #importmap_tags.
  • config.docs_kit.auto_pin = false (in config/application.rb) makes the engine's docs_kit.importmap initializer return early, so docs_kit/controllers stays out of Rails.application.importmap.
  • README "JavaScript" gains "A dedicated docs import map" (the multi-map setup); CHANGELOG [Unreleased] → Added.

With nothing configured the head is byte-identical to 1.2.1.

Closes #93

Test plan

  • spec/docs_kit/configuration_spec.rb: importmap_entry_point default + override; resolved_importmap nil by default, a map as-is, a callable called per read
  • spec/docs_ui/shell_spec.rb: default call passes only "application" (no importmap:); configured entry point + map reach the helper; a callable map is resolved per render
  • spec/docs_kit/engine_spec.rb: config.docs_kit.auto_pin defaults to true; the initializer adds the pin file + sweeper by default and adds neither when auto_pin = false
  • Booted docs/ app: default <head> diffed against origin/main's, byte-identical (CSRF token masked); a custom Importmap::Map with entry docs renders that map's JSON and import "docs"; booting with auto_pin = false leaves the gem's config/importmap.rb out of config.importmap.paths and the drawn map
  • bundle exec rspec — 1063 passed (two seeds)
  • bundle exec rubocop on the changed files — no offenses

No screenshots: the change is <head>-only, and the default render is unchanged.

Deviations & judgment calls

  • Judgment call: one type label, enhancement. The issue also carries performance, but LABELS.md allows exactly one type.
  • Discovery: importmap-rails isn't in the gem's own bundle, so the Shell spec stubs javascript_importmap_tags in a subclass and checks the arguments it receives. The real helper was exercised in the booted docs/ app instead (see test plan).
  • Judgment call: the Shell passes importmap: only when a map is configured, and always passes the entry point ("application" by default). That matches the helper's own defaults, so the default head is unchanged. Confirmed by a before/after head diff.
  • Judgment call: auto_pin = false also skips the cache_sweepers registration for the gem's JS directory, because the whole initializer returns early as the issue specifies. A host that pins the controllers itself only loses dev-time sweeping of the gem's own files.
  • Discovery: config.docs_kit is declared on the engine's config, and Rails shares that with the app's config (class-level Railtie::Configuration options). So config.docs_kit.auto_pin = false in config/application.rb works, because Bundler.require loads the engine first.
  • Overlap: #92 and #95 edit configuration.rb, shell.rb, README and CHANGELOG in parallel PRs. This diff stays limited to the import map lines, so any rebase conflicts should be trivial.

Summary by cubic

Lets a docs app render its import map from a dedicated Importmap::Map and entry point instead of the host's shared application map, and opt out of the engine's auto-pin.

  • c.importmap_entry_point (default "application") and c.importmap (an Importmap::Map or a callable resolved per render) feed the Shell's javascript_importmap_tags.
  • config.docs_kit.auto_pin = false in config/application.rb keeps the gem's docs-nav pin out of Rails.application.importmap.
  • With nothing configured, the rendered head is byte-identical to 1.2.1.