代码之家  ›  专栏  ›  技术社区  ›  Forseti

获取导入模块的文件路径

  •  2
  • Forseti  · 技术社区  · 7 年前

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

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

    为此,我需要一个模块的文件路径, 阴极射线管 是进口的。我怎样才能得到它?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Estus Flask    7 年前

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

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

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

    唯一简单的解决方法是获取一个地方的文件路径 Controller 被叫来。这是通过获取stacktrace来实现的,例如:

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

    问题是这条路 控制器 被称为:

    …/英尺

    @Controller
    export class Foo {...}
    

    ……/巴茨

    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 . 它依赖于节点项目配置,因为它与 esnext

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

    输入元 被传给 @Controller 可以作为 meta.__dirname .