As you probably know a lot of libraries are moving to ESM and deprecating UMD and plain JS on the browser.
Is there a best practice when using ESM and registering a custom component?
I’ve created a custom component based on ESM but I’m wondering if there is a better way.
Here is how it works:
I’m adding the main JS file as a module:
linkFiles: [
{
src: 'js/jonl_avatars_dicebear.js',
type: 'js',
module: true,
defer: true
}
],
Results in:
<script src="/js/jonl_avatars_dicebear.js" type="module" defer="true"></script>
I believe all modules are deferred by default so the defer attribute is probably redundant.
As this library has 20+ styles each contained in it’s own ESM file I need to pass somehow this information to jonl_avatars_dicebear.js
so it can be imported dynamically.
I do this with a droplist control
and the scriptInclude
and includeParam
options
{
name: 'style',
title: 'Style',
type: 'droplist',
required: true,
scriptInclude: 'js/jonl_avatars_dicebear.js',
includeParam: 'style',
values: [
{
title: 'Adventurer',
value: 'adventurer'
},
{
title: 'Adventurer - Neutral',
value: 'adventurer-neutral',
},
{
title: 'Avataaars',
value: 'avataaars',
},
...
So when a style is selected the script tag will be updated and the parameter appended.
<script src="/js/jonl_avatars_dicebear.js?style=adventurer" type="module" defer="true"></script>
The js file contains the logic for the component and the imports but to make it work they need to be called in a specific order:
First a static import from the main library which is common for all the styles, the register the component and finally perform a dynamic import using the style
parameter in the script tag
import { createAvatar } from 'https://cdn.jsdelivr.net/npm/@dicebear/core@5.3/+esm';
let style;
dmx.Component("jonl_avatars_dicebear", {
methods: {
generate: function (seed) {
if (style) {
const avatar = createAvatar(style, {
seed: seed,
dataUri: true
})
return avatar.toDataUriSync();
}
}
}
});
// Has to be added after registering the component or it will delay the register for when the DOM renders the component throwing 'component not found' error.
style = await import(`https://cdn.jsdelivr.net/npm/@dicebear/${new URL(import.meta.url).searchParams.get("style")}@5.3/+esm`)
I’m having certain timing issues that I’m working around in a new version of the JS file but I’m wondering if there is a better way to handle this ESM library in particular and any ESM in general in App Connect.