How do I share dynamically loaded class outside scope

According to the documentation it’s possible to do like this:

let myModule;

if (typeof window === "undefined") {
   myModule = await import("module-used-on-server");
} else {
   myModule = await import("module-used-in-browser");
}

But trying to use this module export (myClass.js):

export class MyClass {
   constructor(){
      console.log('MyClass Constructed');
   }
}

this code (window.initialize() called from a callback) gives me a "MyClass is not a constructor" error in the console (Chrome):

let MyClass;

window.initialize = async () => {
   MyClass = await import('../modules/myClass.js');
   let myClassInstance = new MyClass();
}

This code works though:

window.initialize = async () => {
   let { MyClass } = await import('../modules/myClass.js');
   let myClassInstance = new MyClass();
}

So how do I make the class constructor available outside the function scope?

Thx 😉

This will work but "feels wrong":

let newMyClass = null;

window.initialize = async () => {
   let { MyClass } = await import('../modules/myClass.js');
   newMyClass = () => { return new MyClass(); }
   let myClassInstance = new newMyClass();
}

>Solution :

That’s because you are exporting your class like so:

export class MyClass {
^^^^^^

This is equivalent to this:

class MyClass { ... }
export { MyClass }

That’s the reason why import doesn’t return it without need to use the destructuring. I believe you can use this approach instead

let MyClass

window.initialize = async () => {
   let myClassImport = await import('../modules/myClass.js');
   MyClass = myClassImport.MyClass
   let myClassInstance = new MyClass();
}

Or simply add this class to the global window scope like so

window.initialize = async () => {
   let myClassImport = await import('../modules/myClass.js');
   window.MyClass = myClassImport.MyClass;
   let myClassInstance = new MyClass();
}

Leave a Reply