Widget dependencies as js modules

Nicola Attico
ServiceNow Employee
ServiceNow Employee

I use to add dependencies to widgets when I need third party libraries but nowadays web libraries are progressively presented as modules. The one I'm trying to import uses the following syntax:

 
<script src="//unpkg.com/three"></script>
<script type="importmap">{ "imports": { "three": "https://unpkg.com/three/build/three.module.js" }}</script>
<script type="module">
import { CSS2DRenderer, CSS2DObject } from '//unpkg.com/three/examples/jsm/renderers/CSS2DRenderer.js';
</script>
 
How can we replicate this structure in ServiceNow?
 
Thanks,
Nicola
1 ACCEPTED SOLUTION

Hi @Nicola Attico if this is still of interest to you. I was trying to import a third-party js library that is type module. In the Service Portal dependencies I wasn't able to declare type as module so the library failed. I found a community post that suggested to use an UI Script to append a script tag in the head and the UI Script mapped as Portal Theme dependency of course. It worked for me, hope it helps

 

 

(function() {
	
    var top = document.querySelector('head'); // reach out to the parent window and get the head element

    var script = document.createElement('script'); //create a new script element

    script.src='https://unpkg.com/three/build/three.module.js'; //sets the src attribute

    script.type = 'module'; //sets the type attribute

    script.id = 'XXX';

    top.appendChild(script); // appends the newly created script element at the end of the top window head element

})();

 

 



View solution in original post

4 REPLIES 4

Sai Shravan
Mega Sage

Hi @Nicola Attico ,

 

You can use the importmap.json file to map the import URLs for JavaScript modules. Here's an example of how you can replicate the structure of your third-party library in ServiceNow:

 

1. Create an 'importmap.json' file in your ServiceNow instance. You can do this by creating a new Script Include with the name 'importmap.json' and setting its Script field to the following code:

{
  "imports": {
    "three": "//unpkg.com/three/build/three.module.js"
  }
}

This maps the 'three' module to the https://unpkg.com/three/build/three.module.js URL.

 

2. Create a new UI Script and set its Script field to the following code:

import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js';

// Your widget code goes here

This imports the 'CSS2DRenderer' and 'CSS2DObject' from the 'three/examples/jsm/renderers/CSS2DRenderer.js' module using the mapped three module URL.

 

3. Add your UI Script to your widget dependencies. You can do this by adding the UI Script to your widget's Client Script field.

 

By replicating this structure, you can use third-party libraries that are presented as modules in ServiceNow widgets. Note that this may not work for all third-party libraries, and you should check the documentation for the library to determine if it can be used in this way.

 

Regards,

Shravan

Regards,
Shravan
Please mark this as helpful and correct answer, if this helps you

Hi @Community Alums, thanks for your answer. I'm trying to replicate what you're proposing. About point 1, the importmap, are you actually referring to a script include? I've tried to create one containing the json but it doesn't allow me to save (I tried client callable but it's the same). 
In general, I'm not clear about when ServiceNow includes the js in the page global scope, and when it creates a module scope (<script type="module"></script>). The JS controller of the page is loaded as global scope, but are widget dependencies loaded in separate module scopes?

Thanks,

Nicola

Hi @Nicola Attico if this is still of interest to you. I was trying to import a third-party js library that is type module. In the Service Portal dependencies I wasn't able to declare type as module so the library failed. I found a community post that suggested to use an UI Script to append a script tag in the head and the UI Script mapped as Portal Theme dependency of course. It worked for me, hope it helps

 

 

(function() {
	
    var top = document.querySelector('head'); // reach out to the parent window and get the head element

    var script = document.createElement('script'); //create a new script element

    script.src='https://unpkg.com/three/build/three.module.js'; //sets the src attribute

    script.type = 'module'; //sets the type attribute

    script.id = 'XXX';

    top.appendChild(script); // appends the newly created script element at the end of the top window head element

})();

 

 



Hi @Alex Aluchi, that's very smart, thank you!

I must try it, but I see how that has to work.