javascript 动态导入一个 class 模块并获取 class 的名称

javascript dynamically import a class module and get the name of the class

这个问题是关于 chrome 浏览器的。

我正在尝试动态导入定义为 class 的 javascript 模块。

// data-table.js
export class DataTable extends HTMLElement{
    constructor() {
        super();
    }
    static get tagName() {
        return 'data-table';
    }
} 

我想知道是否有办法在目标代码中获取导入的 class 的名称。 这是我的目标代码,它不起作用。

// 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

这是明显有效的实现,(因为我硬编码了模块 class 名称)

// 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
 

有一个 similar question here 没有任何有效的答案,但那是关于 webpack 的,我直接在浏览器中尝试这个。 我为什么要获得 class 名称? 因为这使我能够简化代码。

事实上你已经在解构{DataTable}(你的语法错误,它需要是({DataTable}))表明它是模块中的一个键,相当于module.DataTablemodule['DataTable']。所以你已经这样了。如果您在开发时确实知道名称 DataTable,那么您已经有了一个字符串。

但您可能不知道该名称,或者它以通用名称公开,例如 export const Component = DataTable,此时您可以通过一致的方式访问它:module.Component

在任何一种情况下,只要你有 class 对象,它只是一个函数,它有 属性 .name,所以你总是可以做 DataTable.name === 'DataTable'.

但以我的专业观点,像这样为了节省一点工作而进行的元编程会导致脆弱的代码,几乎总是在某些时候不方便地中断。

我不认为这通常是个好主意(参见 )但要回答这个问题:

import("foo").then(module => {
    let name = Object.keys(module)[0];
});

当然不是最好的方法,但仍然是一个解决方案。
这仅适用于 export class ....

形式的单个导出

当使用带有动态导入的默认导出时,您需要从返回的对象中解构并重命名“默认”键。

import(route.component)
    .then(({ default: DataTable }) => { 
        console.log(DataTable.tagName);
    });

我只是 运行 遇到了同样的问题,但我在 Node 中使用异步/等待:

const { default: myClass } = await import('/path/to/class.js');

这允许我访问 myClass 对象的静态 属性 方法。