如何在 AWS Lambda 中加载 npm 模块?

How to load npm modules in AWS Lambda?

我使用基于 Web 的编辑器创建了几个 Lambda 函数。到目前为止,一切都很好。我现在想开始使用模块扩展那些模块(例如 Q 代表承诺)。我不知道如何将模块输出到 Lambda,以便我的函数可以使用它们。

我通读了 this,但它似乎涉及从那里设置 EC2 和 运行 Lambda 函数。有一种机制可以在创建函数时上传 zip,但这似乎涉及发送本地开发的函数。由于我在基于 Web 的编辑器中工作,这看起来像是一个奇怪的工作流程。

我如何才能简单地部署一些模块以用于我的 Lambda 函数?

如果不上传 .zip 文件就无法加载 NPM 模块,但实际上您可以将此过程简化为两个快速命令行。

方法如下:

  1. 将您的 Lambda 函数文件放在单独的目录中。这是因为您在本地为 Lambda 安装了 npm 包,并且您希望能够隔离和测试您将上传到 Lambda 的内容。

  2. 在您在第 1 步中创建的单独的 Lambda 目录中使用 npm install packageName 在本地安装 NPM 包。

  3. 确保您的函数在本地 运行ning 时有效:node lambdaFunc.js(您可以简单地注释掉代码中的两行 export.handler 以调整您的代码运行 本地节点)。

  4. 转到 Lambda 的目录并压缩 内容,确保 包含目录本身。

    zip -r lambdaFunc.zip .
    
  5. 如果你安装了aws-cli,如果你想让你的生活更轻松,我建议你安装,你现在可以输入这个命令:

    aws lambda update-function-code --function-name lambdaFunc \
    --zip-file fileb://~/path/to/your/lambdaFunc.zip
    

    (上面的 lambdaFunc 部分没有引号,以防你像我一样疑惑)

  6. 现在您可以在 Lambda 控制台中单击 test

  7. 我建议为以上两个命令添加一个短别名。这是我拥有的更长的 Lambda 更新命令:

    alias up="aws lambda update-function-code --function-name lambdaFunc \
    --zip-file fileb://~/path/to/your/lambdaFunc.zip"
    

需要 .zip 文件才能在 Lambda 中包含 npm 模块。而且您真的不应该将 Lambda 网络编辑器用于任何事情 - 与任何生产代码一样,您应该在本地开发,致力于 git,等等

我的流程:

1) 我的 Lambda 函数通常是大型项目的辅助实用程序,因此我在其中创建了一个 /aws/lambdas 目录来存放它们。

2) 每个单独的 lambda 目录包含一个包含函数代码的 index.js 文件,一个 package.json定义依赖项的文件,以及一个 /node_modules 子目录。 (Lambda 不使用 package.json 文件,只是为了让我们可以在本地 运行 npm install 命令。)

package.json:

{
  "name": "my_lambda",
  "dependencies": {
    "svg2png": "^4.1.1"
  }
}

3) 我 .git 忽略所有 node_modules 目录和 .zip 文件,这样 npm 安装和压缩生成的文件就不会弄乱我们的仓库。

.git忽略:

# Ignore node_modules
**/node_modules

# Ignore any zip files
*.zip

4) 我从 运行 npm install 目录中安装模块,develop/test 本地函数。

5) 我将 lambda 目录压缩并通过控制台上传。

(重要提示:不要使用 Finder 中的 Mac 的 'compress' 实用程序来压缩文件!您必须 运行 从目录根目录中的 CLI - 请参阅 )

zip -r ../yourfilename.zip * 

注意:

如果您在 Mac 上本地安装节点模块,您可能 运行 会遇到问题,因为某些特定于平台的模块在部署到 Lambda 的基于 Linux 的环境时可能会失败。 (参见

解决方案是在从 AMI 启动的 EC2 实例上编译模块,该实例与您使用的 Lambda Node.js 运行时间相对应(请参阅此 Lambda runtimes and their respective AMIs 列表).


另见 AWS Lambda Deployment Package in Node.js - AWS Lambda

希望这对您有所帮助,使用无服务器框架,您可以执行以下操作:

  1. 将这些内容添加到您的 serverless.yml 文件中:
    plugins:
      - serverless-webpack
    custom:
      webpackIncludeModules:
        forceInclude:
          - <your package name> (for example: node-fetch)
  1. 然后创建您的 Lambda 函数,通过 serverless deploy 部署它,serverless.yml 中包含的程序包将为您提供。

有关无服务器的更多信息:https://serverless.com/framework/docs/providers/aws/guide/quick-start/

您现在可以使用 Lambda Layers 来解决这个问题。只需添加一个包含您需要的包的层,它就会 运行 完美。

关注这个post: https://medium.com/@anjanava.biswas/nodejs-runtime-environment-with-aws-lambda-layers-f3914613e20e

npm 模块必须捆绑在您的 nodejs 包中并作为 zip 上传到 AWS Lambda Layers,然后您需要参考下面的 module/js 并使用其中的可用方法。 const mymodule = require('/opt/nodejs/MyLogger');

同样在现在的许多 IDE 中,例如:VSC,您可以安装 AWS 的扩展,然后只需从那里单击上传,无需输入所有这些命令 + 区域。

这是一个例子:

这是一个老问题,但它帮助我找到了一种将新的 Lambda 依赖项添加到 Alexa 技能的非常简单的方法。

像 JohnAllen 的回答一样,您需要在本地计算机上创建一个文件夹,随意命名(随意):

mkdir lambdaFunc
cd lambdaFunc

进入您的文件夹后,使用npm 安装必要的包。对我来说,我需要解析 ISO8601 持续时间(我的命令是 npm install iso8601-duration):

npm install <your-package-here>

安装后,退出该目录,然后压缩它。在 Alexa Skill 开发人员控制台中打开您的 Alexa Skill,然后 select“导入代码”选项。从这里,您将上传您的 .zip 文件和 select 所有代码:

就是这样!然后你可以像我一样导入代码:

const DateConverter = require('iso8601-duration');

在 parcel 上摆弄了几个小时后,我发现它似乎对浏览器中的 运行ning 做了一些假设(即使我告诉它使用 engine: node)。

改为:


esbuild

esbuild!

更容易也更快

只需 运行 npm add --save-dev esbuild,然后将这些脚本添加到您的 package.json:

{
  ...
  "scripts": {
    "build": "esbuild --bundle --minify --platform=node --target=node12 --outdir=build main.js",
    "export": "cd build && zip main.js.zip main.js"
  },
  ...
  "devDependencies": {
    "esbuild": "^0.11.19",
    ...
  }
}

这让我可以使用 aws-sdk,同时仍然进行 tree-shaking 和缩小,同时仍然能够安装其他依赖项,例如 jest 和 eslint,而无需打包整个 node_modules 文件夹.

要在 CI 中构建包,只需: npm ci && npm run build && npm run export

文件 build/main.js.zip 将包含您需要的一切!