Introduction

I developed a rotation plugin called “mirador-rotation” for the latest version of the IIIF viewer Mirador (Mirador 4) and published it on npm. This article explains the process from plugin development to publication, and the integration methods for actual use.

Background

With the major update from Mirador 3 to Mirador 4, the following changes were made:

  • React 16 → React 18
  • Material-UI v4 → MUI v7
  • Many other dependency updates

As a result, existing Mirador 3 plugins no longer work as-is.

Development of mirador-rotation-plugin

Repository

https://github.com/nakamura196/mirador-rotation-plugin

Main Features

  • Image rotation functionality
  • Integration into Mirador 4’s plugin menu

Publishing to npm

The developed plugin is published on npm:

npminstallmirador-rotation

Updating mirador-integration

Referencing the official mirador-integration repository, I built an integration environment compatible with Mirador 4.

Main Changes

ItemOldNew
Mirador3.x4.0.0
React16.14.018.x
Build ToolWebpackParcel
UIMaterial-UI v4MUI v7

package.json

Configured with minimal dependencies:

{}"}de"""""pmmprreiiaeenrrraadaaccceddettnool"-crr":di"-:oe:r"mso"^"""t^1::^a284t.."{.i00^0o..1.n0080""".":,,0,."0^"4.0.0",

Making It Available for External Use

Problem

When building the official mirador-integration as-is, it outputs in ES module format. However, when wanting to load it via a <script> tag from a separate HTML page, there was an issue where Mirador was not defined as a global variable.

<<<!ss/-ccs-rrciiMrTppiihttrpi>atssd>rodcro=.e"vsminie'rwtaedrwo(or{r..kj.s."}>)<;/scriMpitr>adorisnotdefined

Solution

1. Creating a Library Entry Point

Explicitly export as a global variable in index.js:

iiwwmmiippnnooddrroottww..M{Mmiiirmrraiaadrddoaoordrr,oRr=oRto{aattsaitoMi.nioMPrnilaPrudlagoudirgonAirln,=l}mfirf.rorMamoidmro'arm'dRimoorirtarAadaltodliroo'r}n;-;Prloutgaitni;on';

Important: * as MiradorAll retrieves all named exports as well, and the spread syntax flattens them. The reason for this is explained later.

2. Parcel Build Configuration

Specify global format output in package.json:

{}""}"}st,soa"}c"urgrbrgl""iuceoodpietbuitl"satssd:"lpt"":"uD::":tii{Fr{"n{o"pdr:aemrxa"c.t.ej"/ls:d"ib,"sugtil"lodbal-"t,argetglobal"

3. Normalizing File Names

Since Parcel generates file names with hashes by default, a rename script was created:

cccf}ooos)nnn.i};ssssrfctttef)ra(s;ifpddf.pppsaidiraattsiletts=htrenhh/DS.a..rr=iysmjjeernteoonqrcaSiiaue=(rynnmiqdtn((erupiscdd-eiasW(iib(rttissu'ehDtttif(.ihDDls'jr(iid'po)'rr.)ai.i,,j;tnfnsh(odf''_reim)_Exli;da'eric))arh,dn(&oaf&rmi.elfj,eisl'=e)>.e'{n,ds'Wdiitsht('').;js')){

Usage

After building, you can load dist/mirador.js in any HTML:

<<<dss/iccsvrrciiM}rippi,idttrp=>a[t"sdiw}.>drodi].ecr:n,.m=.dmo"v'ormi"midwoar>ieestna<rwm:aid/aeotfoddr'[ierio(,{osRvr{nto>.EItjndasa:t"bi>l'o<ehn/dtPs:tlcpurtsgir:ipu/nte/]>,e)x;ample.com/manifest.json',

The API Flattening Issue

Discovery of the Problem

When using the UMD build of Mirador distributed on unpkg.com, APIs could be called directly as follows:

Mirador.addCompanionWindow(windowId,{content:'info'});

However, running the same code after building with Parcel resulted in the following error:

TypeError:Mirador.addCompanionWindowisnotafunction

Investigating the Cause

Comparing the unpkg.com UMD build with the Parcel build revealed that the difference in export structure was the cause:

Build MethodExport StructureAPI Call
unpkg.com (UMD)FlattenedMirador.addCompanionWindow()
Parcel (default export only)NestedMirador.actions.addCompanionWindow()

In the unpkg.com UMD build, all actions and selectors are flattened at the top level:

GGG...aruEdepxdmdcCoaeovtrmeemppCCataoonnmmyfipproaamonnnomWiiriooeennnndWWdoiiwnno=ddfOoojwwU,==MAyDjg,,build

On the other hand, when only getting the default export with import Mirador from 'mirador':

{}"}de"""""pmmprreiiaeenrrraadaaccceddettnool"-crr":di"-:oe:r"mso"^"""t^1::^a284t.."{.i00^0o..1.n0080""".":,,0,."0^"4.0.0",

0

Solution

Retrieve all named exports in index.js and flatten them with spread syntax:

{}"}de"""""pmmprreiiaeenrrraadaaccceddettnool"-crr":di"-:oe:r"mso"^"""t^1::^a284t.."{.i00^0o..1.n0080""".":,,0,."0^"4.0.0",

1

This results in the following flattened structure in the built file:

{}"}de"""""pmmprreiiaeenrrraadaaccceddettnool"-crr":di"-:oe:r"mso"^"""t^1::^a284t.."{.i00^0o..1.n0080""".":,,0,."0^"4.0.0",

2

Note: mirador-rotation Versions

The mirador-rotation plugin has 4.0.x and 4.1.x versions:

VersionMUITarget
4.0.xv5Mirador 4 alpha early version
4.1.xv7Mirador 4.0.0 official release

Since the official Mirador 4.0.0 release uses MUI v7, please use mirador-rotation 4.1.x.

Summary

This article introduced the development and publication of a plugin for Mirador 4, as well as how to build it as a library that can be used externally.

Key points:

  • Global variables are not defined in ES module format
  • Use import Mirador, * as MiradorAll to get both default export and named exports
  • Flatten with { ...Mirador, ...MiradorAll } for export
  • Use Parcel’s outputFormat: "global" for global format build

Repositories