在aws-cdk v2中处理lambda layers的笔记
简述
希望您能够为我提供一个句子,以便我可以更好地为您继续迭代。
将node_modules进行层次化。
以下是必要的事项。
-
- node_modulesフォルダをLayerのフォルダに指定する
実行する上ではdevDependencyはいらないので、dependencyのみを含んだnode_modulesにする
ビルド時にnode_modulesのファイルはバンドルしないようにする
{
“scripts”: {
“createLayer”: “ts-node lib/process/pre.ts”,
“predev”: “npm run createLayer”,
“dev”: “sam-beta-cdk local start-api”,
“predeploy”: “npm run createLayer”,
“deploy”: “cdk deploy -c @aws-cdk/core:newStyleStackSynthesis=true –profile produser”
}
}
cdk/lib/process/pre.ts
import { bundleNpm } from “./setup”;
// 执行
bundleNpm();
cdk/lib/process/setup.ts
import * as childProcess from ‘child_process’;
import * as fs from ‘fs-extra’;
import * as path from ‘path’
const nodeModulesPath = ‘./bundle-node_modules’;
const commonModulesPath = ‘./bundle-common’;
export const NODE_LAMBDA_LAYER_DIR = path.resolve(process.cwd(), nodeModulesPath);
export const COMMON_LAMBDA_LAYER_DIR = path.resolve(process.cwd(), commonModulesPath);
const NODE_LAMBDA_LAYER_RUNTIME_DIR_NAME = `nodejs`;
const runtimeDirName = path.resolve(process.cwd(), `${nodeModulesPath}/${NODE_LAMBDA_LAYER_RUNTIME_DIR_NAME}`);
const distFilePath = (file: string) => path.resolve(process.cwd(), `${nodeModulesPath}/${NODE_LAMBDA_LAYER_RUNTIME_DIR_NAME}/${file}`)
const srcFilePath = (file: string) => path.resolve(`${process.cwd()}/../${file}`)
export const bundleNpm = () => {
createNodeModules();
};
const createNodeModules = () => {
// 创建捆绑目录
copyPackageJson();
// 安装package.json(仅测试)
childProcess.execSync(`npm install –production`, {
cwd: getModulesInstallDirName(),
env: { …process.env },
});
}
const copyPackageJson = () => {
fs.mkdirsSync(runtimeDirName);
[‘package.json’]
.map(file => fs.copyFileSync(srcFilePath(file), distFilePath(file)));
};
为了确保不将使用externalModules管理的node_modules的脚本包含在bundle中。在这种情况下,是date-fns。
cdk/lib/cdk-stack.ts
import { Stack, StackProps } from ‘aws-cdk-lib’;
import { NodejsFunction } from ‘aws-cdk-lib/aws-lambda-nodejs’;
import * as lambda from ‘aws-cdk-lib/aws-lambda’;
import { Construct } from ‘constructs’;
import { LambdaIntegration, RestApi } from ‘aws-cdk-lib/aws-apigateway’;
import { COMMON_LAMBDA_LAYER_DIR, NODE_LAMBDA_LAYER_DIR } from ‘./process/setup’;
export class CdkStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const nodeModulesLayer = new lambda.LayerVersion(this, ‘NodeModulesLayer’,
{
code: lambda.AssetCode.fromAsset(NODE_LAMBDA_LAYER_DIR),
compatibleRuntimes: [lambda.Runtime.NODEJS_14_X]
}
);
const helloLambda = new NodejsFunction(this, ‘helloLambda’, {
runtime: lambda.Runtime.NODEJS_14_X,
entry: `../src/handler/api/hello.ts`,
layers: [nodeModulesLayer],
bundling: {
externalModules: [
‘aws-sdk’, // 使用Lambda运行时中可用的’aws-sdk’
‘date-fns’, // 需要放入Layer中的模块
],
}
});
const api = new RestApi(this, ‘ServerlessRestApi’, { cloudWatchRole: false });
api.root.addResource(‘hello’).addMethod(‘GET’, new LambdaIntegration(helloLambda));
}
}
将实用程序进行分层化
利用/opt/nodejs/下的路径来配置层。
配置tsconfig和esbuild以确保能够进行转译。
{
"compilerOptions": {
// 省略
"baseUrl": ".",
"paths": {
+ "/opt/nodejs/*": ["src/common/*"],
"@/*" : ["./src/*"]
}
}
}
// 省略
const helloLambda = new NodejsFunction(this, 'helloLambda', {
runtime: lambda.Runtime.NODEJS_14_X,
entry: `../src/handler/api/hello.ts`,
layers: [nodeModulesLayer, commonModulesLayers],
bundling: {
externalModules: [
'aws-sdk', // Use the 'aws-sdk' available in the Lambda runtime
'date-fns', // Layrerに入れておきたいモジュール
+ '/opt/nodejs/*'
],
}
});
// 省略
此時的文件夾結構如下所示。
- tsconfig
- src
- common
- utils
- index.ts
- index.ts
- handler
- api
- hello.ts
以下是使用方法。
import { APIGatewayProxyHandler } from 'aws-lambda';
import { format } from 'date-fns';
- import { formatDate } from '@/common/index';
+ import { formatDate } from '/opt/nodejs/index';
export const handler: APIGatewayProxyHandler = async (event) => {
const datetime = formatDate(new Date(event.requestContext.requestTimeEpoch))
return {
'statusCode': 200,
'body': JSON.stringify({
message: `hello world. ${datetime} = ${event.requestContext.requestTimeEpoch}. now: ${format(new Date(), 'yyyy-MM-dd HH:mm:ss.SSS')}`,
})
};
};
请在母语中进行以下句子的释义,只需给出一种选项:
– 参考
在使用AWS CDK + Typescript环境中,如何有效管理Lambda layer,以及如何将基于TypeScript的Lambda函数拆分为Lambda层。