【问题标题】:Get file path of imported module获取导入模块的文件路径
【发布时间】:2019-01-27 01:08:54
【问题描述】:

我正在为我的控制器编写一个类装饰器。它看起来像:

export function Controller<T extends { new(...args: any[]): {} }> (ctor: T) {
    return class extends ctor {
        public readonly name = name;
    }
}

ctor 是一个用@Controller 装饰的类的构造函数。

控制器文件的完整路径是src/modules/{module}/controllers/{ctrl}Controller.ts。我需要将部分放在花括号中并将它们连接到{module}.{ctrl}

为此,我需要一个模块的文件路径,从中导入 ctor。如何获得?

【问题讨论】:

    标签: node.js typescript annotations node-modules


    【解决方案1】:

    无法从ctor 参数中获取文件路径信息。它只是一个在某处定义的函数。

    基本上,modulectrl 最好在注册时提供给控制器类,因为此时路径是已知的,即:

      for (const filename of filenames) {
        const Ctrl = require(filename).default;
        const [moduleName, ctrlName] = parseCtrlFilename(filename);
        Ctrl._module = moduleName;
        Ctrl._name = ctrlName;
      }
    

    唯一且棘手的解决方法是获取调用Controller 的位置的文件路径。这是通过获取堆栈跟踪来实现的,例如:

    const caller = require('caller-callsite');
    
    export function Controller<T extends { new(...args: any[]): {} }> (ctor: T) {
        const fullPath = caller().getFileName();
        ...
    }
    

    问题在于它是调用Controller 的路径:

    .../foo.ts

    @Controller
    export class Foo {...}
    

    .../bar.ts

    import { Foo } from '.../foo.ts';
    
    // fullPath is still .../foo.ts
    export class Bar extends Foo {}
    

    一种更简单但更可靠的方法是从可用的模块中显式提供文件路径:

    @Controller(__filename)
    export class Foo {...}
    

    import.meta proposal,即supported by TypeScript。它取决于 Node 项目配置,因为它适用于 esnext 目标:

    @Controller(import.meta)
    export class Foo {...}
    

    传递给@Controllerimport.meta可以作为meta.__dirname使用。

    【讨论】:

    • 感谢您详细而彻底的回答。我会采纳你的建议并提供关于导入模块的模块+ctrl 信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    相关资源
    最近更新 更多