node.js - TS/Node.js:获取类实例的绝对路径而不是类本身
问题描述
有没有办法在不将其传递给构造函数的情况下获取创建类实例的文件的路径(__dirname)?例如,
// src/classes/A.ts
export class A {
private instanceDirname: string;
constructor() {
this.instanceDirname = ??
}
}
// src/index.ts
import { A } from "./classes/A"
const a = new A();
// a.instanceDirname === __dirname ✓
我尝试了 callsite,它起作用了,但我不得不做一些我不满意的正则表达式来获得我需要的东西,我还尝试了一个名为caller-callsite的模块,但最终返回的是模块路径,而不是路径创建实例的文件。有解决方法吗?
解决方案
我会让呼叫者传递位置信息。嗅这些东西对我来说似乎是一种代码味道(请原谅双关语)。;-)
但是您可以通过在实例的 V8 调用堆栈上使用正则表达式来做到这一点Error
,但它仍然涉及执行正则表达式(您不喜欢使用 callsite),尽管它是在 V8 自己的堆栈上执行它们,而不是可能会以一种破坏性的方式发生变化(当然不会,除非你升级 Node.js,所以它很容易测试)。看评论:
// A regular expression to look for lines in this file (A.ts / A.js)
const rexThisFile = /\bA\.[tj]s:/i;
// Your class
export class A {
constructor() {
// Get a stack trace, break into lines -- this is V8, we can rely on the format
const stackLines = (new Error().stack).split(/\r\n|\r|\n/);
// Find the first line that doesn't reference this file
const line = stackLines.find((line, index) => index > 0 && !rexThisFile.test(line));
if (line) {
// Found it, extract the directory from it
const instanceOfDirName = line.replace(/^\s*at\s*/, "")
.replace(/\w+\.[tj]s[:\d]+$/, "")
.replace(/^file:\/\//, "");
console.log(`instanceOfDirName = "${instanceOfDirName}"`);
}
}
}
这三个替换可以组合:
const instanceOfDirName = line.replace(/(?:^\s*at\s*(?:file:\/\/)?)|(?:\w+\.[tj]s[:\d]+$)/g, "");
...但为了清楚起见,我将它们分开了;不会对性能产生任何影响。
推荐阅读
- html - 当屏幕尺寸发生变化时,如何调整菜单栏的大小?
- r - 检查 R 中是否存在外部软件的最佳方法是什么?
- c++ - QtCustomPlot 正在绘制我传入的不同时间
- javascript - 仅当元素超出视口时才显示角度 - 修复 ExpressionChangedAfterItHasBeenCheckedError
- pandas - 如何按列分组并查找熊猫中多列的总和
- python - 字段集在 admin django 中没有任何作用
- sql - 计算每天的小时数,最大值输出超过 1 周
- angular - 如何使用 TypesScript(angular) 从剑道组合框中获取文本和值
- reactjs - React/Redux - 编辑列表项后列表不更新
- amazon-web-services - 将 YAML 转换为 JSON 时出错:yaml:第 10 行:此上下文中不允许映射值