javascript es6 modules

MiServer is Dyalog's APL-based web development framework

javascript es6 modules

Postby bry on Mon Apr 11, 2022 6:12 pm

Is it possible to load javascript es6 modules
and use the imports statement in either MiServer or DUI?
If so, how does one do this? I tried doing it indirectly
since import can not be used with inline scripts.
bry
 
Posts: 8
Joined: Wed Oct 11, 2017 6:16 pm

Re: javascript es6 modules

Postby Michael|Dyalog on Wed Apr 13, 2022 9:54 am

Hi bry,

this is perfectly doable.

You can integrate JS-scripts with

      'src={URL}'Add _.script


or, alternatively:

      Use'⍎{URL}  ⍝ (use ⍎ as a shorthand for scripts, ⍕ for CSS styles!)


For example, I have an app that uses modernizr-custom.js. To load it, the Page-Template's Wrap-fn has this statement:

      Use'⍎/assets/modernizr-custom.js'


(adding things you need on all pages via Template is convenient, as it saves you from adding it to every .mipage individually)

This technique works with MiServer as well as with DUI.
Michael|Dyalog
 
Posts: 23
Joined: Thu Mar 02, 2017 4:29 pm

Re: javascript es6 modules

Postby bry on Fri Apr 15, 2022 4:34 am

Hi Michael

Thx for the reply. I will try what you have suggested.

I have been using scripts which load local files
e.g. Three.js and GLTFLoader.js. I shut off CORS using
the Moesif Origin & CORS changer. This all works as
long as I don't use modules and scripts of type="importmap"

Bryant
bry
 
Posts: 8
Joined: Wed Oct 11, 2017 6:16 pm

Re: javascript es6 modules

Postby bry on Sun Apr 17, 2022 7:53 pm

Hi Michael
I agree that using a template is a good idea. That was my plan
after doing some simple testing. My real issue is with how
MiServer/DUI handles javascript namespaces when they differ from
the from the module specifier. I realize the javascript namespace
is a local name. Here is a non-working example. The module
specifier is three and the javascript namespace is THREE. The
GLTFLoader expects THREE. I'd appreciate your insights.

Non Working Example

File: testm2.mipage
:Class testm2 : MiPage
∇ Compose;tb
:Access public
Add '<script type="module" src="./testm2.js"></script>'

:EndClass

File: testm2.js
import * as THREE from "../Threejs/r139/three.module.js";
console.log("got THREE");
import {GLTFLoader} from "../Threejs/AddOns/GLTFLoader.module.js";
console.log("got GLTFLoader");

Console output:
Uncaught TypeError: Failed to resolve module specifier "THREE". testm2.mipage:1
Relative references must start with either "/", "./", or "../".
bry
 
Posts: 8
Joined: Wed Oct 11, 2017 6:16 pm

Re: javascript es6 modules

Postby Michael|Dyalog on Mon Apr 18, 2022 3:15 pm

Hmm, could you pls. post the directory structure showing where all involved files (testm2.mipage, testm2.js and three.module.js) are located?
I think the only issue you have is referring those files.
Michael|Dyalog
 
Posts: 23
Joined: Thu Mar 02, 2017 4:29 pm

Re: javascript es6 modules

Postby bry on Mon Apr 18, 2022 6:12 pm

Hi Michael
I took your suggestion and made a template (subclass of MiPage).
I then added all of the required scripts to load javascript libraries
in the head. I made all the paths relative to ServerRoot. I then used
that template for my tests and it all worked. Here is the code for the template:

:Class ThreePage : #.MiPage

∇ {r}←Wrap;lang;header;home;menu
:Access Public

Head.Add '<script src="/Threejs/r139/three.js"></script>'
Head.Add '<link rel="stylesheet" href="/Threejs/AddOns/normalize.css">'
Head.Add '<link rel="stylesheet" href="/Threejs/AddOns/style.css">'
Head.Add '<script src="/Threejs/AddOns/TweenMax.min.js"></script>'
Head.Add '<script src="/Threejs/AddOns/OrbitControls.js"></script>'
Head.Add '<script src="/Threejs/AddOns/GLTFLoader.js"></script>'
Head.Add '<script src="/Threejs/AddOns/VertexNormalsHelper.js"></script>'
Head.Add '<script src="/Threejs/AddOns/VertexTangentsHelper.js"></script>'
Head.Add '<script src="/Threejs/AddOns/stats.js"></script>'
Head.Add '<script src="/Threejs/AddOns/dat.gui.js"></script>'

⍝ call the base class Wrap function
r←⎕BASE.Wrap


I tbased my application scripts on #.ThreePage and it all worked.

However, I still have some questions:
1) In this model, I have to load the entire javascript library for each file.
I would like to use modules and import only the functions that I need.
2) Does the "Use" syntax allow for javascript "async" and "defer" options?
3) Does "Use" guarantee to load the scripts into the head?

The directory structure for test2.mipage and test2.js problem is:

C:/bwyDUI/DUI.dws is ServerRoot
C:/bwyDUI/Threejs/r139/three.js
C:/bwyDUI/Threejs/r139/three.module.js
C:/bwyDUI/Threejs/AddOns/GLTFLoader.js
C:/bwyDUI/Threejs/ThreeLearn/test2.mipage
C:/bwyDUI/Threejs/ThreeLearn/test2.js

Thanks in advance for all your help.
Bryant
bry
 
Posts: 8
Joined: Wed Oct 11, 2017 6:16 pm

Re: javascript es6 modules

Postby Michael|Dyalog on Tue Apr 19, 2022 10:33 am

Hi Bryant,
I'm currently working on a repro and have hit some issues that need a bit more time. I'll be back with a more qualified answer...

Meanwhile, I'd like to at least answer what I can:

2) I don't think Use can do that - but you can achieve that with
Code: Select all
'async defer src={path}'[Body.]Add _.script


3) Yes, I think you can rely on that.

More later!
Michael|Dyalog
 
Posts: 23
Joined: Thu Mar 02, 2017 4:29 pm

Re: javascript es6 modules

Postby Michael|Dyalog on Wed Apr 20, 2022 9:52 am

Duh, this is confusing indeed. After googling around, I saw that we're definitely not alone with these issues and three.js itself might be part of the issue. But I must admit that I do not feel I understand the matter sufficiently well enough to judge ;)

I have build what I assumed would be a "nice example" - and then found out it wouldn't work in Firefox, throwing the same error as the one you had. When I changed to Chrome, it seemed to work!

I don't what browser you were using - but maybe you can try this with Chrome.

Also, I notice you had stored those files in the DUI folder and below, so I'd like to recommend a "good practice": put your code into a separate location. That will allow you to easily update DUI and having your code separate also allows to handle it like a "distinct application", version-control with GitHub etc.

So, my sample follows this recommendation. You can unzip it anywhere and then run it with
Code: Select all
DUI.Run'c:/threejs-app'8080
(8080 being the port on which DUI will listen).
If using MiServer, do
Code: Select all
Start'c:/threejs-app'
. (Replace "c:/threejs-app" with the path you unzipped it to)

The base class of the actual page is "ThreePage" and it exposes a field "LoadModules" through which you can define which module a certain page uses. "testm2" makes use of it to access three and the "GLTFLoader". If ALL pages need threejs, then it wouldn't need to be included by page, but could always be added in the template instead. (Implementing that change is left as an excercise to the reader)

I hope that code & structure are clear enough, but admittedly it's not...eh..overcommented. So feel free to ask if anything is unclear!

Because the sample includes all of threejs, its 300MB even after zipping. I hesitate to upload such a beast to the forum, but you can fetch it from my cloud drive.

I hope it all goes well...
Michael|Dyalog
 
Posts: 23
Joined: Thu Mar 02, 2017 4:29 pm

Re: javascript es6 modules

Postby bry on Wed Apr 20, 2022 3:47 pm

Michael

Many Thanks!!! This is really helpful. I downloaded the zip from your
cloud, so you can remove it if you need the space. I have been using chrome,
but making the template fixed most of the problem. I will test your approach
and then see if I can import less than the entire Three.js library instead of *

Bryant
bry
 
Posts: 8
Joined: Wed Oct 11, 2017 6:16 pm

Re: javascript es6 modules

Postby Michael|Dyalog on Wed Apr 20, 2022 3:49 pm

Good luck - and I'd be interested to know how things are going...! ;)
Michael|Dyalog
 
Posts: 23
Joined: Thu Mar 02, 2017 4:29 pm

Next

Return to MiServer

Who is online

Users browsing this forum: No registered users and 1 guest