簡體   English   中英

從 node.js 上運行的 typescript 中的基數 class 獲取派生 class 的文件名?

[英]Get filename of derived class from base class in typescript running on node.js?

我正在尋找一種方法來從運行在 node.js 上的 class 中的基數 class 獲取派生的 class 的文件名。這方面的一個例子是:

export abstract class Foo {
    constructor() { }
    name() { return (__filename); }
    print() { console.log(this.name()); }
}

巴茨

import { Foo } from './Foo';

export class Bar extends Foo {
    constructor() { super(); }
}

主.ts

import { Bar } from './Bar';

let bar = new Bar();
bar.print(); // should yield the location of Bar.ts

由於涉及的文件數量和清潔度,我希望將其限制在Foo class 中,而不是在每個派生的 class 中覆蓋name() function。

我能夠用代碼解決這個問題:

private getDerivedFilePath(): string {
    let errorStack: string[] = new Error().stack.split('\n');
    let ret: string = __filename;
    let baseClass: any = ThreadPoolThreadBase;
    for (let i: number = 3; i < errorStack.length; i++) {
        let filename: string = errorStack[i].slice(
            errorStack[i].lastIndexOf('(') + 1,
            Math.max(errorStack[i].lastIndexOf('.js'), errorStack[i].lastIndexOf('.ts')) + 3
        );
        let other: any = require(filename);
        if (other.__proto__ === baseClass) {
            ret = filename;
            baseClass = other;
        } else {
            break;
        }
    }
    return (ret || '');
}

添加到Foo ,當從構造函數調用以設置私有 _filename 屬性時,對於上述示例之外的 inheritance 鏈,只要文件的結構是使用 class 的默認導出結構,該屬性就會起作用。 There may also be a caveat that if a base class from which a derived object is inheriting directly is initialized as a separate instance within the constructor of any member of the inheritance chain it could get confused and jump to another independent derived class - so it's a有點駭人聽聞的解決方法,如果有人想出更好的東西,我會很感興趣,但是想發布此內容以防有人偶然發現此問題並且對他們有用。

您可以使用require.cache獲取所有緩存的 NodeModule對象並過濾它以找到您的模塊。

https://nodejs.org/api/modules.html#requirecache

class ClassA {
    public static getFilePath():string{
        const nodeModule = this.getNodeModule();
        return (nodeModule) ? nodeModule.filename : "";
    }
    
    public static getNodeModule(): NodeModule | undefined{
        const nodeModule = Object.values(require.cache)
            .filter((chl) => chl?.children.includes(module))
            .filter((mn)=> mn?.filename.includes(this.name))
            .shift();
        return nodeModule;
    }
}
class ClassB extends ClassA {
    constructor(){}
}

const pathA = ClassA.getFilePath(); //Must return the absolute path of ClassA
const pathB = ClassB.getFilePath(); //Must return the absolute path of ClassB

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM