Azure TypeScript函数无法确定入口点,求排查方案
在Azure Linux环境下开发Node.js TypeScript函数时,遇到「无法确定函数入口点」的错误,以下是相关信息及排查建议:
项目结构
<root-directory> ├── README.md ├── dist ├── bin ├── dependencies ├── host.json ├── local.settings.json ├── node_modules ├── package-lock.json ├── package.json ├── sealworker │ ├── constants │ ├── errors │ ├── function.json │ ├── index.ts │ ├── interfaces │ ├── sample.dat │ ├── services │ ├── utils │ └── worker.ts └── tsconfig.json
function.json配置
{ "bindings": [ { "authLevel": "function", "type": "httpTrigger", "direction": "in", "name": "req", "methods": [ "get", "post" ] }, { "type": "http", "direction": "out", "name": "res" } ], "entryPoint": "sealWorkerFunction", "scriptFile": "../dist/sealworker/index.js" }
/sealworker/index.ts代码
import { AzureFunction, Context, HttpRequest } from "@azure/functions"; import workerExec from "./worker"; const sealWorkerFunction: AzureFunction = async function ( context: Context, req: HttpRequest ): Promise<void> { const responseMessage = "example"; const result = await workerExec(req, context); context.res = { // status: 200, /* Defaults to 200 */ body: responseMessage, }; }; export default { sealWorkerFunction };
/sealworker/worker.ts代码
import "dotenv/config"; import "reflect-metadata"; import { HttpRequest, Context } from "@azure/functions"; const workerExec = async (req: HttpRequest, context: Context) => { context.log("start...."); const message = req.body; context.log("message: ", message); return { result: "dummy" }; }; export default workerExec;
错误信息
Result: Failure Exception: Worker was unable to load function sealworker: 'Unable to determine function entry point: sealWorkerFunction. If multiple functions are exported, you must indicate the entry point, either by naming it 'run' or 'index', or by naming it explicitly via the 'entryPoint' metadata property.' Stack: Error: Worker was unable to load function sealworker: 'Unable to determine function entry point: sealWorkerFunction. If multiple functions are exported, you must indicate the entry point, either by naming it 'run' or 'index', or by naming it explicitly via the 'entryPoint' metadata property.' at /azure-functions-host/workers/node/dist/src/worker-bundle.js:2:14706 at t.LegacyFunctionLoader. (/azure-functions-host/workers/node/dist/src/worker-bundle.js:2:14945) at Generator.next () at o (/azure-functions-host/workers/node/dist/src/worker-bundle.js:2:13387) at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
构建后dist/sealworker/index.js代码
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const worker_1 = __importDefault(require("./worker")); const sealWorkerFunction = function (context, req) { return __awaiter(this, void 0, void 0, function* () { const name = req.query.name || (req.body && req.body.name); const responseMessage = name ? "Hello, " + name + ". This HTTP triggered function executed successfully." : "This HTTP triggered function executed successfully. Pass a name in the query string or in the req body for a personalized response."; context.log(`Http function processed req for url "${req.url}"`); const message = req.body; context.log("type of message: ", typeof message); context.log("message: ", message); const result = yield (0, worker_1.default)(req, context); context.res = { // status: 200, /* Defaults to 200 */ body: responseMessage, }; }); }; exports.default = { sealWorkerFunction }; //# sourceMappingURL=index.js.map
排查建议
1. 修正函数导出方式
当前代码将函数包裹在对象中导出(export default { sealWorkerFunction }),导致Azure Functions无法识别到指定的sealWorkerFunction入口。需要改为直接导出函数:
// 修改index.ts的导出语句 export default sealWorkerFunction;
或者使用命名导出方式,同时保持function.json的entryPoint配置:
// 改为命名导出 export const sealWorkerFunction: AzureFunction = async function(...) { ... };
2. 验证构建后代码的导出结构
修改后重新构建项目,检查dist/sealworker/index.js的导出部分,确保是直接导出函数而非对象:
// 正确的导出形式 exports.default = sealWorkerFunction;
3. 确认function.json配置正确性
- 检查
scriptFile路径是否正确:相对于function.json所在目录,确保../dist/sealworker/index.js指向实际生成的构建文件 - 确认
entryPoint的名称与代码中导出的函数名完全一致(注意大小写敏感)
4. 检查tsconfig.json配置
确保tsconfig的以下配置符合Azure Functions要求:
module设置为commonjs(Node.js运行时使用CommonJS模块系统)outDir设置为dist,确保构建产物输出到正确目录target设置为兼容Node.js版本的目标(如ES2020)
内容的提问来源于stack exchange,提问作者Kid_Learning_C

