在aws-cdk v2中处理lambda layers的笔记

简述

希望您能够为我提供一个句子,以便我可以更好地为您继续迭代。

将node_modules进行层次化。

以下是必要的事项。

    • node_modulesフォルダをLayerのフォルダに指定する

実行する上ではdevDependencyはいらないので、dependencyのみを含んだnode_modulesにする

ビルド時にnode_modulesのファイルはバンドルしないようにする

在dev(本地确认)或deploy之前,执行Layer文件夹的脚本pre.ts。根据npm的规则,使用以pre脚本名定义的脚本,在目标脚本执行之前执行,因此利用这一点。cdk/package.json
{
“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层。

广告
将在 10 秒后关闭
bannerAds