部署Node.js到AWS Lambda时TypeORM报‘No metadata for Silo’错误
解决TypeORM在AWS Lambda单文件打包下的
EntityMetadataNotFoundError问题 问题原因
把TypeScript代码打包成单个index.js部署到Lambda后,TypeORM找不到实体元数据,核心原因有三个:
- 打包后文件结构完全改变,基于本地路径的实体扫描(比如
__dirname + '../classes/Entities{.js,.ts}')彻底失效 - 用
require("../classes/Entities")传入的是整个模块对象,不是实体类本身,TypeORM无法识别 - 编译或打包过程中,TypeORM依赖的装饰器元数据(
@Entity这类)没被正确保留,导致无法生成实体元数据
解决方案
1. 直接在DataSource中显式引用实体类
修改src/db/dbConnections.ts,去掉require和路径匹配,直接导入并传入实体类:
import { Silo, SiloLevel, SiloSecondaryKeyword, SiloLevelSiloLevel } from "../classes/Entities"; import { DataSource } from "typeorm"; import { SnakeNamingStrategy } from "typeorm-naming-strategies"; const DB_USER = process.env.DB_USER; const DB_HOST = process.env.DB_HOST; const DB_NAME = process.env.DB_NAME; const DB_PASSWORD = process.env.DB_PASSWORD; const DB_PORT = process.env.DB_PORT; export const dataSource = new DataSource({ type: "postgres", username: DB_USER, host: DB_HOST, database: DB_NAME, password: DB_PASSWORD, port: +DB_PORT, // 直接传入实体类,不要传模块或路径 entities: [Silo, SiloLevel, SiloSecondaryKeyword, SiloLevelSiloLevel], namingStrategy: new SnakeNamingStrategy() }); dataSource.initialize() .then(() => console.log("Data Source has been initialized!")) .catch(err => console.error("Error during Data Source initialization", err));
2. 强制保留装饰器元数据
检查tsconfig.json,确保开启装饰器相关配置,这是TypeORM识别实体的基础:
{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true, "target": "ES2020", "module": "CommonJS", "outDir": "./dist", // 其他配置按需添加 } }
3. 调整打包工具配置(如果用webpack/esbuild)
如果用webpack或esbuild打包单文件,必须配置工具保留装饰器元数据:
- webpack配置示例:
module.exports = { module: { rules: [ { test: /\.ts$/, use: [ { loader: "ts-loader", options: { compilerOptions: { experimentalDecorators: true, emitDecoratorMetadata: true } } } ], exclude: /node_modules/ } ] }, // 其他打包配置 };
- esbuild配置示例:
先安装依赖esbuild-plugin-tsc,然后配置:
const esbuild = require('esbuild'); const tscPlugin = require('esbuild-plugin-tsc'); esbuild.build({ entryPoints: ['src/index.ts'], bundle: true, outfile: 'dist/index.js', platform: 'node', target: 'node18', plugins: [tscPlugin({ tsconfig: './tsconfig.json' })], }).catch(() => process.exit(1));
4. 别用tsc的outFile
tsc的outFile只支持AMD/System模块,Lambda用的是CommonJS,强行用outFile会导致模块导入混乱。建议先用outDir编译到目录,再用打包工具合并成单文件。
验证步骤
- 本地编译后,检查
dist目录下的实体类代码,确认@Entity等装饰器没有被编译丢失 - 打包成单文件后,用
aws-lambda-local在本地模拟Lambda运行,排查是否还报错 - 部署到Lambda后,查看CloudWatch日志,确认数据源初始化成功、实体可正常访问
内容的提问来源于stack exchange,提问作者Yona Eisenberg
相关产品推荐
相关产品推荐

