我正在为我的 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
参数获取文件路径信息。它只是一个在某处定义的函数。
基本上,module
和 ctrl
最好在注册时提供给 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/