On the good use of importmap declarations

Hello all,

Since XWiki 18.0.0RC1 it is possible to declare importmap from the properties of a maven module.
This allows JavaScript modules to easily be imported by other modules in the browser.

I naively started using this mechanism by declaring the importmap values in the importer of the module.
For instance, if a WebJar module needs Vue, I am adding the following property in its pom (in addition to adding the Vue WebJar in the runtime dependencies):

<xwiki.extension.javascript.modules.importmap>{
  "vue": "org.webjars.npm:vue/dist/vue.runtime.esm-browser.prod.js"
}</xwiki.extension.javascript.modules.importmap>

This approach does not seem ok in practice because each module using Vue has to duplicate this importmap declaration.

What I propose is to move to an approach where the provider of the module declares the importmap.
In the case where the module is defined inside xwiki-platform, this is easy since we have control over the POM and can easily add the xwiki.extension.javascript.modules.importmap property pointing to the right JavaScript in the WebJar.
But things get more complex for webjars we do not control (e.g., the org.webjars.npm:vue WebJar used in the example above).

The best option I have in mind is to wrap the WebJar in a new module in xwiki-platform, only to add the xwiki.extension.javascript.modules.importmap.
For instance, for Vue we would:

  • Add a new xwiki-platform-webjar-vue module (in xwiki-platform-core/xwiki-platform-webjars/xwiki-platform-webjar-vue).
  • Add the xwiki.extension.javascript.modules.importmap property with the right declaration.
  • Add org.webjars.npm:vue in the runtime dependencies.
  • Replace all imports of org.webjars.npm:vue with org.xwiki.platform:xwiki-platform-webjar-vue (but that wouldn’t cover contrib extensions unless they have a parent pom of 18.2.0+).

WDYT? Do you have an idea of another mechanism that would allow to declare the importmap for external WebJars in a less intrusive way?
Thanks!

I would prefer a way to inherit the import map from a parent POM. When an external WebJar is used as a dependency of multiple XWiki modules we add the version to the parent POM to make sure all XWiki modules use the same version. It would be nice to be able to declare the import map in the parent POM as well, where we declare the shared version. Of course, a child module should be able to extend the import map.

Thanks,
Marius

After some brainstorming on the chat, we made some progress that could mitigate the listed limitation:

  • By looking at what mvnpm does, we realized that a lot of the entries can be directly derived from the package.json files provided in the WebJars (so in most cases, wrapping to define an importmap is not needed). See XWIKI-24064: Derive the importmap from package.json in webjars by manuelleduc · Pull Request #5239 · xwiki/xwiki-platform · GitHub
  • I found one important case where what in the package.json is not ok. Since we want to externalize Vue (i.e., not have it re-bundled in each extension using Vue, which would lead to a lot of duplication), we need to use the vue.runtime.esm-browser.prod.js version of Vue. Sadly, the package.json of the Vue webjars points to vue.runtime.esm-bundler.prod.js. So for exceptional cases like this one, I propose to use the wrapping strategy from my initial proposal
  • Contrib extensions that absolutely need to have a parent version 18.0.0+ and that cannot move to 18.2.0+ will have to duplicate the declaration in their importmap (so probably a very marginal case).
  • For our own WebJars, we keep declaring the importmap entry for themselves as proposed in my initial message.