获取导入模块的文件路径
Get file path of imported module
我正在为我的控制器编写一个 class 装饰器。看起来像:
export function Controller<T extends { new(...args: any[]): {} }> (ctor: T) {
return class extends ctor {
public readonly name = name;
}
}
ctor
是用 @Controller
修饰的 class 的构造函数。
控制器文件的完整路径是 src/modules/{module}/controllers/{ctrl}Controller.ts
。我需要将部分放在花括号中并将它们连接成 {module}.{ctrl}
.
为此,我需要从中导入 ctor
的模块的文件路径。如何获得?
无法从 ctor
参数获取文件路径信息。它只是一个在某处定义的函数。
基本上,module
和 ctrl
最好在注册时提供给控制器 class,因为此时路径是已知的,即:
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 which is supported by TypeScript。它取决于 Node 项目配置,因为它适用于 esnext
target:
@Controller(import.meta)
export class Foo {...}
传递给 @Controller
的 import.meta
可以作为 meta.__dirname
.
使用
我正在为我的控制器编写一个 class 装饰器。看起来像:
export function Controller<T extends { new(...args: any[]): {} }> (ctor: T) {
return class extends ctor {
public readonly name = name;
}
}
ctor
是用 @Controller
修饰的 class 的构造函数。
控制器文件的完整路径是 src/modules/{module}/controllers/{ctrl}Controller.ts
。我需要将部分放在花括号中并将它们连接成 {module}.{ctrl}
.
为此,我需要从中导入 ctor
的模块的文件路径。如何获得?
无法从 ctor
参数获取文件路径信息。它只是一个在某处定义的函数。
基本上,module
和 ctrl
最好在注册时提供给控制器 class,因为此时路径是已知的,即:
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 which is supported by TypeScript。它取决于 Node 项目配置,因为它适用于 esnext
target:
@Controller(import.meta)
export class Foo {...}
传递给 @Controller
的 import.meta
可以作为 meta.__dirname
.