As showed here (or here) we can use external class definition in many browsers and NodeJs... But the most useful way to load the external class is
import('./MyClass.js').then(({default: MyClass}) => {
let x = new MyClass(); // using here!
// ... but it is not global, is AN ISLAND IN A BLOCK
}); // async loading
... but it is not global, is an island in a async block. So, how to do it globally?
TESTING GLOBAL ALTERNATIVES AND ERRORS:
const MyClass = () => import('/MyClass.js'); // ok, but...
let x = new MyClass()
// Uncaught TypeError: MyClass is not a constructor
const MyClass = await import('/MyClass.js');
// Uncaught SyntaxError: await is only valid in async function
The module = await import(moduleFile)
form is suggested here.
For "global class" suppose an external Javascript file MyClass.js
like this:
export default class MyClass {
constructor(x) {
this.val=x? x: "Hello!"
console.log("MyClass ok...")
}
}
As showed here (or here) we can use external class definition in many browsers and NodeJs... But the most useful way to load the external class is
import('./MyClass.js').then(({default: MyClass}) => {
let x = new MyClass(); // using here!
// ... but it is not global, is AN ISLAND IN A BLOCK
}); // async loading
... but it is not global, is an island in a async block. So, how to do it globally?
TESTING GLOBAL ALTERNATIVES AND ERRORS:
const MyClass = () => import('/MyClass.js'); // ok, but...
let x = new MyClass()
// Uncaught TypeError: MyClass is not a constructor
const MyClass = await import('/MyClass.js');
// Uncaught SyntaxError: await is only valid in async function
The module = await import(moduleFile)
form is suggested here.
For "global class" suppose an external Javascript file MyClass.js
like this:
export default class MyClass {
constructor(x) {
this.val=x? x: "Hello!"
console.log("MyClass ok...")
}
}
Share
Improve this question
edited Mar 5, 2019 at 18:29
Peter Krauss
asked Mar 5, 2019 at 18:12
Peter KraussPeter Krauss
14k28 gold badges184 silver badges332 bronze badges
5
- Global global, or module global? – T.J. Crowder Commented Mar 5, 2019 at 18:21
-
Hi @T.J.Crowder, I need to use the class,
let x = new MyClass()
... AndMyClass
must be at the global namespace. – Peter Krauss Commented Mar 5, 2019 at 18:22 - That's usually a footgun, because the load is asynchronous, so code could try to use it before it's been filled in. – T.J. Crowder Commented Mar 5, 2019 at 18:25
- Why are you yelling? That's how all-caps es across to many of us. – Heretic Monkey Commented Mar 5, 2019 at 18:26
- @HereticMonkey, sorry, edited my "copy/paste" from code to text. – Peter Krauss Commented Mar 5, 2019 at 18:30
1 Answer
Reset to default 9Generally, you don't want to do things globally when you're using modules. That's part of the point of modules.
If you're importing dynamically, then by the nature of what you're doing it's going to be an asynchronous process, which means having code that waits for it to plete (for instance, a then
handler or using await
in an async
function).
You could write to a global in the then
handler (or after await
in an async
function), but it's normally a bad idea, since there will be a period of time when the global doesn't have the value (yet).
// **NOT** RECOMMENDED
import("/MyClass.js")
.then(cls => {
window.MyClass = cls; // Or `global.MyClass = cls;` on Node.js
})
.catch(error => {
// Handle error
});
Or to a module global:
// **NOT** RECOMMENDED
let MyClass;
import("/MyClass.js")
.then(ns => {
MyClass = ns.default;
})
.catch(error => {
// Handle error
});
(Note that what you receive from dynamic import
is the module namespace object. In your case you're using the default export, which is accessible via the default
property on the MNO.)
In both cases, though, code may try to use it before it's been filled in. More: How do I return the response from an asynchronous call?
Instead, basically, put all of the code that needs that class in a then
handler, or in an async
function after await
. Live Example
(async () => {
const {default: MyClass} = await import("./MyClass.js");
let c = new MyClass();
// ...
})()
.catch(error => {
// Handle/report error
console.error(error);
});
(Notice the destructuring to get MyClass
from the default on the MNO.)
See also: How can I use async/await at the top level?