node.js - اجرای toString روی یک تابع در Typescript منجر به کاراکترهای عجیب میشود (path_1, (0, promises.writeFile))
من در تلاش هستم یک تابع را به رشته تبدیل کنم تا آن را به یک نخ کاری ارسال کرده و در آنجا اجرا کنم. با این حال، رشته حاوی کاراکترهای عجیب است جایی که کد وارد شده استفاده میشود.
import { HttpStatus } from '@nestjs/common';
import { access, constants, writeFile } from 'fs/promises';
import path from 'path';
import { Error as CustomError } from 'src/util/Error';
import { AbstractTask } from 'src/util/queue/AbstractTask';
export class CreateFileTask extends AbstractTask<boolean> {
private path: string;
private buffer: Buffer;
constructor(path: string, buffer: Buffer) {
super();
this.path = path;
this.buffer = buffer;
}
public async execute(): Promise<boolean> {
return new Promise(async (resolve, reject) => {
let resolvedPath = path.resolve(this.path);
try {
await access(resolvedPath, constants.F_OK);
} catch (e) {
reject(new CustomError(`file at ${this.path} already exists`, HttpStatus.CONFLICT));
}
try {
await writeFile(resolvedPath, this.buffer);
} catch (e) {
if (e instanceof Error) {
reject(new CustomError(e.message, HttpStatus.INTERNAL_SERVER_ERROR));
} else {
reject(new CustomError(e as string, HttpStatus.INTERNAL_SERVER_ERROR));
}
}
resolve(true);
});
}
}
فراخوانی new CreateFileTask(...).execute.toString() منجر به کاراکترهای عجیب میشود:
execute() {
return new Promise(async (resolve, reject) => {
let resolvedPath = path.resolve(this.path);
try {
await (0, promises_1.access)(resolvedPath, promises_1.constants.F_OK);
}
catch (e) {
reject(new Error_1.Error(`file at ${this.path} already exists`, common_1.HttpStatus.CONFLICT));
}
try {
await (0, promises_1.writeFile)(resolvedPath, this.buffer);
}
catch (e) {
if (e instanceof Error) {
reject(new Error_1.Error(e.message, common_1.HttpStatus.INTERNAL_SERVER_ERROR));
}
else {
reject(new Error_1.Error(e, common_1.HttpStatus.INTERNAL_SERVER_ERROR));
}
}
resolve(true);
});
}
استفاده از import * as path from "path" به نظر میرسد مشکل ماژول path را حل کند. چرا اینطور است؟ آیا راهحل دیگری به جای استفاده از import * as ... from ... که به معنای وارد کردن همه چیز حتی اگر نیاز نباشد، وجود دارد؟
پاسخ شماره ۱
آن «کاراکترهای عجیب» نسخه کامپایلشده کد شما هستند که خروجی باندلر شماست و در حقیقت همان چیزی است که اجرا میشود. اما این مشکل واقعی اینجا نیست.
من تلاش میکنم یک تابع را به رشته تبدیل کنم تا آن را به یک رشته کاری ارسال کنم و در آنجا اجرا کنم.
شما نمیتوانید یک تابع را به رشته تبدیل کنید و انتظار داشته باشید که در سمت دیگر قابل اجرا باشد. بنابراین، سعی نکنید توابع را رمزگذاری کرده و به صورت رشته ارسال کنید.
برای اینکه شما بتوانید یک تابع را برای اجرا ارسال کنید، باید هر مقداری که در آن تابع استفاده میشود را از دامنه آن تابع ارسال کنید. و این واقعاً عملی نیست.
به عنوان مثال:
const foo = 123
function logFoo() { console.log(foo) }
console.log(logFoo.toString()) // "function logFoo() { console.log(foo) }"
اینجا logFoo به خوبی به یک رشته تبدیل میشود، اما به یک متغیر محلی foo ارجاع میدهد که در رشته خروجی گنجانده نشده است. بنابراین احتمالاً اگر سعی کنید آن را eval کنید و اجرا کنید، خراب خواهد شد.
این مشکل خیلی بدتر است اگر شما واردات از فایلهای دیگر داشته باشید، یا ارجاع به یک کلاس مانند this.something.
پس این رویکرد اصلاً کار نخواهد کرد. این کار را نکنید.
در عوض، کد خود را در عامل بارگذاری کنید، سپس پیامهایی به آن ارسال کنید که شامل خود داده باشند.
