最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ecmascript 6 - javascript dynamically import a class module and get the name of the class - Stack Overflow

programmeradmin1浏览0评论

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
Add a comment  | 

3 Answers 3

Reset to default 10

When 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.

发布评论

评论列表(0)

  1. 暂无评论