Node.js TypeScript Monorepo中Azure Functions执行func start报错
问题背景
我搭建了如下结构的Node.js TypeScript Monorepo:
libraries/ lib1/ lib2/ package.json tsconfig.json web-api/ function1/ function.json index.ts function2/ function.json index.ts host.json package.json tsconfig.json package.json tsconfig.json
已在根目录package.json中配置workspaces,执行npm run build --workspace=web-api可正常完成构建,web-api的dist目录包含libraries和web-api子文件夹,以及tsc生成的JS文件与sourcemap。但进入web-api目录执行func start时,触发运行时错误:
Worker was unable to load function function1: 'Cannot find module 'libraries/lib1/constants'`
嵌套的tsconfig已配置对libraries文件夹的引用,但func start似乎在错误路径查找模块,请问需要额外配置还是执行方式有误?
复现步骤
- 进入根目录
- 执行
npm install - 执行
npm run build --workspace=functionapp1 - 进入functionapp1目录
- 执行
func start
预期结果:函数应用成功启动,HTTP触发器可正常访问
实际结果:函数应用因找不到libraries文件夹启动失败
问题原因
Azure Functions的func start默认从当前目录加载代码,但Monorepo构建后,libraries的编译产物存放在web-api的dist目录中,而Functions运行时默认读取src目录的源码,同时模块解析路径未正确指向dist内的libraries产物,导致找不到模块。
解决方案
方案1:指定dist目录为Functions工作目录
启动时通过--script-root参数指定编译后的dist目录作为运行根目录:
func start --script-root dist/functionapp1
此方式让Functions运行时直接加载dist下的编译代码,而dist内已包含正确的libraries模块引用路径,可直接解析。
方案2:调整tsconfig与function.json配置
- 在web-api/functionapp1的
tsconfig.json中,确保baseUrl和paths正确映射libraries路径:
{ "compilerOptions": { "baseUrl": ".", "paths": { "libraries/*": ["../libraries/*"] }, // 其他编译配置... }, "references": [{"path": "../libraries"}] }
- 修改每个function的
function.json,指定scriptFile为dist目录下的对应JS文件:
例如function1的function.json:
{ "scriptFile": "../dist/functionapp1/function1/index.js", // 其他函数配置... }
方案3:利用npm workspaces软链接(开发阶段适用)
根目录执行npm install时,workspaces会自动在web-api的node_modules中创建libraries的软链接。需确保TypeScript编译时保留模块解析路径,此方案更适合开发调试,生产环境仍建议依赖dist产物。
内容的提问来源于stack exchange,提问作者Norrec

