背景

mirador-annotations は、IIIF ビューア Mirador にアノテーション機能を追加するプラグインです。

従来のプロジェクトは以下の構成でした:

  • ビルドツール : nwb (Create React App ベース)
  • UI ライブラリ : Material-UI v4
  • Mirador : 3.x
  • React : 17.x

しかし、以下の問題が発生していました:

  1. nwb のメンテナンス停止 - nwb は長期間更新されておらず、依存関係の競合が頻発
  2. npm install の失敗 - 古い依存関係により、新しい環境でのセットアップが困難に
  3. セキュリティ脆弱性 - 古いパッケージに多数の脆弱性警告

これらの問題を解決するため、以下への移行を決定しました:

  • ビルドツール : Vite
  • UI ライブラリ : MUI v7
  • Mirador : 4.x
  • React : 18.x

移行作業の概要

1. ビルドツールの移行 (nwb → Vite)

nwb の設定ファイルを削除し、vite.config.js を新規作成しました。

主なポイント:

e}x)pcr};vooe;irntd}r}ttsue,e,etrfgsd].dndiloe,ceernold''''ofn{aebvu@@rrnavf:aepeeeefutl:emmaail=-{::ooccgtj{tttt.ls'[ii'-jdogoo,dsealnnofdo//miEgbrs'nnlaet,evolayC(bTclomahtenoli'dfds,'ie',g,,((p{romcoedses.}c)wd=(>),{);

2. Material-UI の移行 (v4 → v7)

  • @material-ui/*@mui/* に変更
  • makeStylessx prop に置き換え
  • Grid コンポーネントの API 変更に対応 (itemxs props が size に統合)
<<GGrriiddis(t(iMeMzUmUeII=x{vsv14=72){)}1>2}>

3. Mirador 4.x への対応

Mirador 4.x では、アクションやセレクターのインポート方法が変更されました:

iasirgmcemeeptlpctoieoeVrocriitnttvssoei({.r({AbMrsMnliae.irnerccgreoCateeactadiitdeanoovVoitvrneirviasAseos3,ni4Ane.nb.n(sxsolxn.()ete)o..laCt..etaa).cint)tovionaor(sns.e,.s}.(g).ef.tr.Vo)imsi'bmlierCaadnovra's;es}from'mirador';

ハマったポイント

1. menuItemRef.current.focus is not a function エラー

症状

アノテーションが存在するキャンバスに移動すると、以下のエラーが発生:

TypeError:menuItemRef.current.focusisnotafunction

原因

Mirador 4.x の CanvasAnnotations コンポーネントは、<MenuList autoFocusItem> を使用しています。この autoFocusItem は、リスト内の最初のアイテムに自動的にフォーカスを当てる機能ですが、フォーカス対象の要素が focus() メソッドを持っている必要があります。

問題は CanvasListItem コンポーネントにありました:

c}lar}sesnr)de;Cet<arud/n(ri{dv)nvtia>hvs{(i>L{si/.s*ptrIdotipevsm.cehxritelefdnrdesn}Compofnoecnuts({)/}

MUI の MenuItem は内部的に ref を使ってフォーカス制御を行いますが、CanvasListItem がクラスコンポーネントで <div> をラップしていたため、ref が正しくフォワードされず、focus() メソッドが見つからないエラーが発生していました。

解決策

CanvasListItem を関数コンポーネントに書き換え、forwardRef を使用して ref を <li> 要素に直接フォワードするようにしました:

ic}}mo,)pnacr);osnre;rtnent<tofsul/Ct)triroo{{{lRaanenn./cient=[fMM.*h>avi>i(=oo.icaos{uuoltsn{Hrsstd,LioeeehridvfELee{s,e}nerntrtaP/}uIcievr}sthnreoeeig==pSml,{{stdrhh}a=rseaateefnnefntdd,o,IllrseeuwHlMMsaoiooervuuCdoessoRtreenehiELtfennee(rgtax(P]evt{rre,o=}}pfsuosrewSatradtRee(ffa}lsfer)o;m'react';

学び

  • MUI v5+ の MenuListautoFocusItem は、子コンポーネントが適切に ref をフォワードすることを期待している
  • カスタムリストアイテムコンポーネントを作成する際は、forwardRef を使用して ref を DOM 要素に渡す必要がある
  • クラスコンポーネントから関数コンポーネントへの移行時は、ref の扱いに注意が必要

2. CompanionWindow が表示されない

症状

「Create new annotation」ボタンをクリックしても、何も表示されない。コンソールを確認すると:

  • addCompanionWindow アクションは正常にディスパッチされている
  • AnnotationCreation コンポーネントの render() は呼ばれている
  • しかし画面には何も表示されない

また、以下の警告が出ていました:

Wianrn`iCnogm:paFnaiiolneWdinpdroowp`,tybpuet:iTthsevparloupe`idsir`eucntdieofni`neids`.markedasrequired

原因

Mirador は CompanionWindow コンポーネントを2種類エクスポートしています:

  1. CompanionWindow - ベースコンポーネント(props を手動で渡す必要あり)
  2. ConnectedCompanionWindow - Redux 接続版(props が自動的にストアから取得される)

移行前のコードでは CompanionWindow を直接使用していましたが、Mirador 4.x では ConnectedCompanionWindow を使用する必要がありました。

impoCrotmp{anCioomnpWainnidoonwWinRddeoidwruex}ctfiroonm,'pmoisriatdioorn';props

解決策

ConnectedCompanionWindow をインポートするように変更:

import{ConnectedCompanionWindowasCompanionWindow}from'mirador';

これにより、directionposition などの必要な props が Redux ストアから自動的に取得されるようになりました。

学び

  • Mirador のコンポーネントには、ベース版と Redux 接続版が存在する場合がある
  • プラグイン開発時は、どちらのバージョンを使用すべきか確認が必要
  • 「コンポーネントは render されているのに表示されない」場合は、必須 props が不足している可能性を疑う

その他の対応事項

draft-js の global 参照エラー

draft-js は global オブジェクトを参照しますが、ブラウザ環境では存在しません。Vite の設定で対応:

d}efgilnoeb:al{:'globalThis',

@emotion/react の重複警告

Mirador と本プラグインの両方が @emotion/react をバンドルすることで発生。resolve.dedupe で解決:

<<GGrriiddis(t(iMeMzUmUeII=x{vsv14=72){)}1>2}>

0

legacy-peer-deps の必要性

@psychobolt/react-paperjs が React 17 を peer dependency として要求するため、.npmrclegacy-peer-deps=true が引き続き必要。


まとめ

今回の移行で最も時間がかかったのは、以下の2点でした:

  1. ref フォワーディングの問題 - MUI の内部動作を理解し、適切に ref を扱う必要があった
  2. Connected コンポーネントの使用 - Mirador のエクスポート構造を理解する必要があった

どちらも、ライブラリの内部実装を理解することで解決できました。移行作業では、エラーメッセージだけでなく、ライブラリのソースコードを確認することが重要です。

デモ

移行後の動作は以下のデモサイトで試すことができます:

https://nakamura196.github.io/mirador-annotations/

参考リンク