Skip to content

ChakraCore : Dynamic Module Import #6870

@bkimman

Description

@bkimman

As part of building C samples for chakra, am now working on modules.

For this I am using the examples posted by Mozilla at
https://github.com/mdn/js-examples/tree/main/module-examples

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules is the place where they explain the examples.

All the examples have a canvas module which in turn uses square, circle and triangle modules to draw the different shapes, reporting their actions in an Unordered List.

I created a pseudo DOM in a js script which I parsed in the console application before parsing the main module.

The first module is parsed with JsModuleParse.

In the FetchImportedModuleCallback callback, I queued other imported modules for parsing.

The parsing continues till there are no more modules to parse - this results in a call to NotifyModuleReadyCallback on the root module.

I am then calling JsModuleEvaluation.

With this sequence, all the examples, except for one, were working fine.

The one which is different uses dynamic module import like this...

let squareBtn = document.querySelector('.square'); squareBtn.addEventListener('click', () => { import('./modules/square.js').then((Module) => { let square1 = new Module.Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue'); square1.draw(); square1.reportArea(); square1.reportPerimeter(); }) }); 

I have managed to get it to work as follows:

The main module and the canvas module are parsed first; and the main module is evaluated. This is the same as the sequence for the other examples.

Then I call the 'click' function on the button to trigger the dynamic import.

When this function is invoked, the following is the sequence:

a) callback is received in FetchImportedModuleCallback for the dynamically imported module.
b) in the callback I invoked JsModuleParse
c) the callback NotifyModuleReadyCallback was received
d) in this callback I invoked JsModuleEvaluate and then JsGetModuleNamespace

But the result of the click did not show up.

Since this is a dynamic import which returns a Promise, I set a PromiseContinuationCallback callback before calling the 'click' function.

When the module is evaluated, the PromiseContinuationCallback callback is invoked twice .. in both cases the 'task' parameter is a JsFunction. A call to toString on this function indicates it is a native function.

While calling the function I passed a single argument of the module's namespace. With this, the result of the click showed up just right. bingo!

When I passed no arguments to the function, or 'undefined' as the argument, the results of the click were incomplete but no exception was raised.

Questions:

a) What is the argument that should be passed to the 'task' function - in my simple program, I knew the promise was triggered by the import and so I passed the module's namespace; but in a more complex example this would not be the case - so how does one determine what the argument should be?

The JsSetPromiseContinuationCallback provides a callbackState parameter but if I call this in the NotifyModuleReadyCallback, will it not overwrite a previously set callbackState value?

b) When is the FetchImportedModuleFromScriptCallback callback made? Looking at the name, I thought it would be used for dynamic imports, but the callback made for dynamic imports was still FetchImportedModuleCallback.

c) In FetchImportedModuleCallback for the dynamic module, I created a new ModuleRecord and called JsModuleParse .. when this function returned, I returned the new module record in the out parameter JsModuleRecord* dependentModuleRecord. This did not cause any problem - is this the way the dynamic import should be handled?

Thanks

Kimman

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions