This question is about chrome browser.
I am trying to dynamically import a javascript module defined as a class.
// data-table.js
export class DataTable extends HTMLElement{
constructor() {
super();
}
static get tagName() {
return 'data-table';
}
}
I would like to know if there is a way to get the name of the imported class in the the target code. here is my target code that does not work.
// router.js
...//some code
if(route === matched){
// dynamically import the component
import(routeponent)
.then( module => {
// anyway to get classname DataTable here??
})
};
...//rest of the code
Here is obvious implementation that works, (because I hardcoded the module class name)
// router.js
...//some code
if(route === matched){
// dynamically import the component
import("components/data-table.js")
.then( {DataTable} => {
cost t = DataTable.tagName;
// code to handle module stuff
})
};
...//rest of the code
There is a similar question here without any working answer, but that is about webpack and I am trying this directly in browser. Why would I want to get the class name? Because that gives me ability to simplify code.
This question is about chrome browser.
I am trying to dynamically import a javascript module defined as a class.
// data-table.js
export class DataTable extends HTMLElement{
constructor() {
super();
}
static get tagName() {
return 'data-table';
}
}
I would like to know if there is a way to get the name of the imported class in the the target code. here is my target code that does not work.
// router.js
...//some code
if(route === matched){
// dynamically import the component
import(route.component)
.then( module => {
// anyway to get classname DataTable here??
})
};
...//rest of the code
Here is obvious implementation that works, (because I hardcoded the module class name)
// router.js
...//some code
if(route === matched){
// dynamically import the component
import("components/data-table.js")
.then( {DataTable} => {
cost t = DataTable.tagName;
// code to handle module stuff
})
};
...//rest of the code
There is a similar question here without any working answer, but that is about webpack and I am trying this directly in browser. Why would I want to get the class name? Because that gives me ability to simplify code.
Share Improve this question asked Mar 10, 2021 at 13:24 Ali MasoodAli Masood 1571 silver badge7 bronze badges 3- Why would you try to import a class that you don't even know? Why do you even name the class? – Bergi Commented Jun 8, 2021 at 0:32
- it is a router implementation effort. when a route is matched, I would like to import the corresponding class and run it. as the whole matching part is dynamic, it is unknown beforehand which class will be needed in the router. – Ali Masood Commented Sep 18, 2021 at 3:26
- The route definition that the user passes to your router then should contain the class name to use. Or if all you have is a list of modules, make sure that each of the modules implements the same interface - namely a default export. – Bergi Commented Sep 18, 2021 at 10:50
3 Answers
Reset to default 10When using a default export with dynamic imports, you need to destructure and rename the "default" key from the returned object.
import(route.component)
.then(({ default: DataTable }) => {
console.log(DataTable.tagName);
});
I just ran into this same problem, but I'm using async / await in Node:
const { default: myClass } = await import('/path/to/class.js');
This allowed me to access the static property methods of the myClass object.
I don't think that's generally a good idea (see @Steven's Answer) but to answer the question:
import("foo").then(module => {
let name = Object.keys(module)[0];
});
Certainly not the best way to do it, but a solution nonetheless.
This only works for single exports in the form of export class ...
.
The fact that you're already destructuring {DataTable}
(your syntax is wrong, it needs to be ({DataTable})
) shows that it's a key in the module, equivalent to module.DataTable
or module['DataTable']
. So you already have it that way. If you really know the name DataTable
at dev-time, then you already have a string.
But presumably you don't know the name, or it's exposed under a common name, such as export const Component = DataTable
, at which point you have a consistent way to access it: module.Component
.
In either case, as long as you have the class object, it's just a function, which has the property .name
, so you can always just do DataTable.name === 'DataTable'
.
But in my professional opinion, metaprogramming like this to save a little work leads to fragile code that almost always breaks inconveniently at some point.