获取导入模块的文件路径 [英] Get file path of imported module

查看:92
本文介绍了获取导入模块的文件路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a class decorator for my controllers. It looks like:

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

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

ctor is a constructor of a class decorated with @Controller.

控制器文件的完整路径为src/modules/{module}/controllers/{ctrl}Controller.ts.我需要将花括号中的零件连接起来,并将它们连接到{module}.{ctrl}.

Full path to the controller's file is src/modules/{module}/controllers/{ctrl}Controller.ts. I need to get parts in curly braces and concatenate them into {module}.{ctrl}.

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

To do so I need a filepath of module from which ctor is imported. How can I obtain it?

推荐答案

无法从ctor参数获取文件路径信息.这只是在某处定义的功能.

There is no way to get file path information from ctor parameter. It's just a function that was defined somewhere.

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

Basically, module and ctrl preferably have to be provided to controller class on registration, since the path is known at this moment, i.e.:

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

唯一且棘手的工作方法是获取调用Controller的位置的文件路径.这是通过获取stacktrace来实现的,例如:

The only and hacky workarount is to get file path of a place where Controller was called. This is achieved by getting stacktrace, e.g:

const caller = require('caller-callsite');

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

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

The problem is that it's the path where Controller is called:

.../foo.ts

@Controller
export class Foo {...}

.../bar.ts

import { Foo } from '.../foo.ts';

// fullPath is still .../foo.ts
export class Bar extends Foo {}

一种不太hacky且更可靠的方法是从可用的模块中显式提供文件路径:

A less hacky and more reliable way is to provide file path explicitly from the module where it is available:

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

import.meta提案,它是

There is import.meta proposal which is supported by TypeScript. It depends on Node project configuration because it works with esnext target:

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

传递给@Controller

import.meta可以用作meta.__dirname.

import.meta that was passed to @Controller can be consumed as meta.__dirname.

这篇关于获取导入模块的文件路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆