使用 esbuild 为特定平台构建 Sharp 并使用 NodejsFunction lambda 进行部署

Dmi*_*nko 7 aws-lambda sharp esbuild

我正在尝试部署一个使用 Sharp 进行图像处理的 Lambda 函数。我不想使用 docker 构建——我必须使用 esbuild。这是我在 cdk 中的 lambda 定义:

  const processUploadedImageLambdaFunction = new NodejsFunction(
      this,
      `${deployEnv()}_processUploadedImage`,
      {
        runtime: lambda.Runtime.NODEJS_18_X,
        // handler: "index.handler",
        entry: `${__dirname}/../lambda-fns/lambdas/processUploadedImage/index.ts`,
        bundling: {
          target: "node18",
          sourceMap: true,
          sourceMapMode: SourceMapMode.INLINE,
          sourcesContent: false,
          externalModules: ["sharp"],
          nodeModules: ["sharp"],
          command: ["npm rebuild sharp --arch=x64 --platform=linux sharp"],
        },

        insightsVersion,
        logRetention,
        // memorySize: 10240,
        memorySize: 3008,
        timeout: cdk.Duration.seconds(30),
        environment: {
          ...config,
        },
      },
    )
Run Code Online (Sandbox Code Playgroud)

当函数运行时出现以下异常:

{
    "errorType": "Error",
    "errorMessage": "\nSomething went wrong installing the \"sharp\" module\n\nCannot find module '../build/Release/sharp-linux-x64.node'\nRequire stack:\n- /var/task/node_modules/sharp/lib/sharp.js\n- /var/task/node_modules/sharp/lib/constructor.js\n- /var/task/node_modules/sharp/lib/index.js\n- /var/task/index.js\n- /var/runtime/index.mjs\n\nPossible solutions:\n- Install with the --verbose flag and look for errors: \"npm install --ignore-scripts=false --verbose sharp\"\n- Install for the current linux-x64 runtime: \"npm install --platform=linux --arch=x64 sharp\"\n- Consult the installation documentation: https://sharp.pixelplumbing.com/install",
    "stack": [
        "Error: ",
        "Something went wrong installing the \"sharp\" module",
        "",
        "Cannot find module '../build/Release/sharp-linux-x64.node'",
        "Require stack:",
        "- /var/task/node_modules/sharp/lib/sharp.js",
        "- /var/task/node_modules/sharp/lib/constructor.js",
        "- /var/task/node_modules/sharp/lib/index.js",
        "- /var/task/index.js",
        "- /var/runtime/index.mjs",
        "",
        "Possible solutions:",
        "- Install with the --verbose flag and look for errors: \"npm install --ignore-scripts=false --verbose sharp\"",
        "- Install for the current linux-x64 runtime: \"npm install --platform=linux --arch=x64 sharp\"",
        "- Consult the installation documentation: https://sharp.pixelplumbing.com/install",
        "    at Object.<anonymous> (/var/task/node_modules/sharp/lib/sharp.js:31:9)",
        "    at Module._compile (node:internal/modules/cjs/loader:1254:14)",
        "    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)",
        "    at Module.load (node:internal/modules/cjs/loader:1117:32)",
        "    at Module._load (node:internal/modules/cjs/loader:958:12)",
        "    at Module.require (node:internal/modules/cjs/loader:1141:19)",
        "    at require (node:internal/modules/cjs/helpers:110:18)",
        "    at Object.<anonymous> (/var/task/node_modules/sharp/lib/constructor.js:8:1)",
        "    at Module._compile (node:internal/modules/cjs/loader:1254:14)",
        "    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)"
    ]
}

Run Code Online (Sandbox Code Playgroud)

我缺少什么?如何使用 esbuild 为特定平台构建 Sharp 并使用 NodejsFunction lambda 进行部署?有没有办法用简单的 esbuild 来做到这一点,并避免使用更先进的技术,如 docker 和图层?

Fel*_*ert 1

更新:对于 Sharp >= v0.33 来说,似乎不能开箱即用。考虑使用 lambda 层进行 Sharp 或遵循AWS Lambda 的 Sharp 文档


我可以通过以下选项使用捆绑(不是 docker 捆绑且无 lambda 层)在 lambda NodeJS CDK 函数中成功使用Sharp 。esbuild也适用于 Github Action 工作流程。

(注:用于--arch=arm64CDK lambda.Architecture.ARM_64

new NodejsFunction(this, "SOME_ID", {
  // ...
  bundling: {
    externalModules: ["sharp"],
    nodeModules: ["sharp"],
    commandHooks: {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      beforeBundling(inputDir: string, outputDir: string): string[] {
        return [];
      },
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      beforeInstall(inputDir: string, outputDir: string): string[] {
        return [];
      },
      afterBundling(inputDir: string, outputDir: string): string[] {
        return [`cd ${outputDir}`, "rm -rf node_modules/sharp && npm install --no-save --arch=x86 --platform=linux sharp"];
      }
    }
  }
  // ...
});
Run Code Online (Sandbox Code Playgroud)

通过aws-solutions/serverless-image-handler找到了此解决方案