node.js - 获取导入模块的文件路径

标签 node.js typescript annotations node-modules

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

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

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

Controller 文件的完整路径为src/modules/{module}/controllers/{ctrl}Controller.ts。我需要获取大括号中的部分并将它们连接到 {module}.{ctrl}

为此,我需要从中导入 ctor 的模块的文件路径。我怎样才能获得它?

最佳答案

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

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

  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 {...}
传递给 @Controller

import.meta 可以作为 meta.__dirname 使用。

关于node.js - 获取导入模块的文件路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51938613/

相关文章:

java - @Async 在 REST 类中不起作用

node.js - 在 Ubuntu 上更新 Node.js - 更新后版本未更改

TypeScript:将对象放入变量时,类型保护不适用于 switch 语句

css - 通过调用函数问题来改变按钮类CSS颜色的 Angular

typescript - TypeScript 类型 Array<string> 中缺少索引签名

java - Java Aspect 是否可以参数化

node.js - 是否有可与 CouchDB 配合使用的基于 NodeJS 的全文搜索索引器(如 Lucene)?

node.js - 如何使用sharp包压缩PNG文件?

mysql - (async) 使用 sequelize 和 node 在 mysql 数据库中创建多个寄存器

java - Spring注解与xml混合问题