基于Yarn Workspaces+TypeScript的Monorepo部署AWS Lambda依赖问题解决
Monorepo下AWS Lambda独立部署包缺失依赖的解决办法
问题根源
你当前的部署包只取了dist/tasks/my-task目录的内容,但my-shared共享包和第三方依赖的node_modules都在dist根目录,Lambda打包时不会自动向上查找这些文件,导致运行时缺依赖。
方案一:手动调整构建流程,把依赖塞进任务目录
修改你的构建和依赖安装步骤,将必要的依赖和共享包都放到单个任务的目录下:
- 先执行原有的编译命令:
yarn build
- 复制各package.json到dist对应位置:
cp tasks/my-task/package.json dist/tasks/my-task/ cp my-shared/package.json dist/my-shared/ cp package.json dist/
- 在任务目录下安装依赖,指定把
node_modules装在当前目录(默认会装到dist根):
yarn --cwd dist/tasks/my-task/ install --modules-folder ./node_modules
- 把
my-shared的编译产物复制到任务目录的node_modules里(因为Yarn Workspaces用的是软链,Lambda需要实际文件):
cp -r dist/my-shared dist/tasks/my-task/node_modules/my-shared/
现在dist/tasks/my-task里就包含了自身代码、所有第三方依赖以及my-shared,CDK打包时就能把所有必要文件都包含进去。
方案二:用CDK的NodejsFunction自动打包(推荐)
CDK的@aws-cdk/aws-lambda-nodejs模块基于esbuild,可以自动处理TS编译、Monorepo依赖打包,完全省去手动复制文件的麻烦:
- 先安装这个模块:
yarn add @aws-cdk/aws-lambda-nodejs
- 修改CDK代码,替换成
NodejsFunction:
import { NodejsFunction } from '@aws-cdk/aws-lambda-nodejs'; // ... const handler = new NodejsFunction(this, "HelloMonorepo", { runtime: lambda.Runtime.NODEJS_14_X, entry: '../tasks/my-task/index.ts', // 直接指向源码TS文件,不用先编译 handler: "hello", bundling: { // 如果有不需要打包的依赖(比如AWS SDK)可以加在这里 // externalModules: ['aws-sdk'], nodeModules: ['my-shared'], // 明确打包Monorepo里的共享包 }, });
这个方式会自动把my-task的代码、my-shared的代码以及所有依赖打包成一个独立的Lambda部署包,每个任务单独打包,完全符合你“每个Lambda对应独立部署包”的需求。
方案三:自定义CDK Asset打包逻辑
如果需要更灵活的控制,可以让CDK在打包时自动合并所需文件:
修改CDK代码,指定打包命令,把my-task、my-shared和node_modules都复制到输出目录:
const handler = new lambda.Function(this, "HelloMonorepo", { runtime: lambda.Runtime.NODEJS_14_X, code: lambda.Code.fromAsset("../dist", { bundling: { image: lambda.Runtime.NODEJS_14_X.bundlingImage, command: [ 'bash', '-c', 'cp -r tasks/my-task/ my-shared/ node_modules/ /asset-output/ && rm -rf /asset-output/node_modules/.bin' ], }, }), handler: "my-task/index.hello", // 注意这里的handler路径要对应打包后的结构 });
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

