[importmap-rails] ネストされたパッケージパスの正確な識別処理を実装

rails/importmap-rails

背景

importmap-railsでは、JavaScriptパッケージのバージョン管理を行う際、パッケージ名をURLから抽出する処理が実装されています。しかし、photoswipe/lightbox@github/webauthn-json/browser-ponyfill のようなネストされたパスを持つパッケージに対して、パッケージ名の識別が正しく機能していませんでした。

この問題により、outdated版のチェック時に誤ったパッケージ名で検索が行われ、バージョン比較が正常に動作しないという課題が発生していました(#321)。

技術的な変更内容

パッケージ名抽出ロジックの追加

lib/importmap/npm.rb に新しいプライベートメソッド extract_base_package_name が追加されました。このメソッドは、ネストされたパスを持つパッケージから、ベースとなるパッケージ名を正確に抽出します。

def extract_base_package_name(package)
  if package.start_with?("@")
    # Scoped packages can have nested paths, e.g. @scope/package/subpath
    parts = package.split("/", 3)
    parts.size > 2 ? parts.first(2).join("/") : package
  else
    # Non-scoped packages - just take the first part
    package.split("/").first
  end
end

このロジックは以下の2つのケースを処理します:

  1. スコープ付きパッケージ@ で始まる):最初の2つのパートを結合してパッケージ名とする

    • @github/webauthn-json/browser-ponyfill@github/webauthn-json
    • @github/webauthn-json@github/webauthn-json(変更なし)
  2. 通常のパッケージ:最初のパートのみを取得

    • photoswipe/lightboxphotoswipe
    • photoswipephotoswipe(変更なし)

packages_with_versionsメソッドの改良

抽出されたパッケージ名とバージョンのペアに対して、新しいロジックを適用し、重複を排除する処理が追加されました。

with_versions.map! do |package, version|
  [extract_base_package_name(package), version]
end.uniq!

この変更により、同一パッケージの異なるサブパスが複数存在する場合でも、ベースパッケージ名として1つにまとめられます。

実際の動作例

ネストされたパスを持つパッケージの場合

Importmap定義:

pin "photoswipe/lightbox", to: "https://ga.jspm.io/npm:photoswipe@5.4.4/dist/photoswipe-lightbox.esm.js"
pin "photoswipe", to: "https://ga.jspm.io/npm:photoswipe@5.4.4/dist/photoswipe.esm.js"

変更前: photoswipe/lightboxphotoswipe が別々のパッケージとして認識される

変更後: 両方とも photoswipe@5.4.4 として正しく認識され、outdatedチェックが正常に機能する

スコープ付きパッケージのネストされたパスの場合

pin "@github/webauthn-json/browser-ponyfill", to: "https://ga.jspm.io/npm:@github/webauthn-json@2.1.1/dist/esm/webauthn-json.browser-ponyfill.js" # @2.1.1

変更後: @github/webauthn-json@2.1.1 として正しく識別され、npmレジストリへの問い合わせが正常に行われる

テストカバレッジ

今回の変更では、以下のケースに対する包括的なテストが追加されています:

  • ネストされたパッケージパスの抽出
  • バージョンコメント付きネストパッケージの処理
  • スコープ付きパッケージのネストパス処理
  • 通常のスコープ付きパッケージの処理
  • outdatedチェックの正常動作

これにより、様々なパッケージ構造に対する堅牢性が確保されました。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

ガイドライン準拠 ✓ PASS

記事構成とDiffDaily Styleへの準拠状況

記事構成の3要素(Title, Context, Technical Detail)が明確に記載されています。コードブロック前後の空行やGitHubリンク記法など、カスタムMarkdown構文も正しく使用されており、可読性が高いです。

  • 記事構成(Title、Context、Technical Detail)
  • DiffDaily Styleガイド準拠
  • カスタムMarkdown活用
  • 対象読者への適合性
技術的整合性 ✓ PASS

技術的な正確性と表現の適切性

記事で引用されているコードはDiffの内容と完全に一致しています。追加された `extract_base_package_name` メソッドのロジック解説も技術的に正確です。動作例はテストコードを基にしており、変更内容の理解を助ける上で効果的です。

  • 技術用語の正確性
  • コード例の正確性
  • 説明の技術的正確性
PR内容との整合性 ✓ PASS

元のPR情報との一致度

記事内のすべての主張は、PRのDescription、Diff、およびテストコードによって裏付けられています。特に「テストカバレッジ」のセクションは、PRのテストファイルの内容を正確に反映しており、ハルシネーションは見られません。

  • タイトル・説明の一致
  • Diff内容の正確な反映
  • 推測の排除