【问题标题】:How to load npm modules in AWS Lambda?如何在 AWS Lambda 中加载 npm 模块?
【发布时间】:2016-03-30 00:28:18
【问题描述】:

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

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

如何简单地部署一些模块以在我的 Lambda 函数中使用?

【问题讨论】:

标签: amazon-web-services npm aws-lambda


【解决方案1】:

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

方法如下:

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

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

  3. 确保您的函数在本地运行时正常工作:node lambdaFunc.js(您可以简单地注释掉代码中的两行 export.handler 以调整您的代码以在本地与 Node 一起运行)。

    李>
  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"
    

【讨论】:

  • 您可能需要明确说明您的目标区域:aws lambda update-function-code --function-name lambdaFunc --region eu-west-1 --zip-file fileb://~/path/to/your/lambdaFunc.zip
  • 虽然看起来工作量很大,但要完成这些工作,构建这些 lambda 表达式确实是一种更好的方法......非常感谢!
  • 在使用这些步骤时,我不得不使用 --zip-file fileb:// 而不是 --zip-file file://
  • 确保仅压缩目录的内容,并且从 CLI 执行(使用 Mac 的“压缩”命令)查找器will NOT work)。
  • 这非常有用.. 至少缺少两件事才能使这项工作对我有用... 1) 对我来说是 --zip-file fileb: 而不是 file。 2)在 MacOS 上,它似乎带有 3 个斜杠,例如喜欢fileb:///Users/wio/Documents
【解决方案2】:

需要.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) 我 .gitignore 所有 node_modules 目录和 .zip 文件,以便从 npm 安装和压缩生成的文件不会弄乱我们的 repo。

.gitignore:

# Ignore node_modules
**/node_modules

# Ignore any zip files
*.zip

4) 我从目录中运行npm install 来安装模块,并在本地开发/测试功能。

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

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

zip -r ../yourfilename.zip * 

注意:

如果您在 Mac 上本地安装节点模块,您可能会遇到问题,因为某些特定于平台的模块在部署到 Lambda 的基于 Linux 的环境时可能会失败。 (见https://stackoverflow.com/a/29994851/165673

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


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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 直到此刻才知道图层。谢谢埃尔达德!
    • 为什么不使用 AWS Toolkit?似乎这是试图接管“所有这一切”? (关于如何做这一切的文档中有一些令人沮丧的碎片...... a)基于 Web 的编辑器 b)手动 .zip 上传 c)SAM d)现在的层 e)AWS Toolkit ......作为开发人员试图导航) /跨度>
    【解决方案4】:

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

    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/

    【讨论】:

    • 你需要先安装它serverless plugin install --name pluginName
    【解决方案5】:

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

    这是一个例子:

    【讨论】:

    • AWS VS Code 扩展可以在here找到
    【解决方案6】:

    摆弄了几个小时后,我发现它似乎对在浏览器中运行做出了一些假设(即使我告诉它使用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 &amp;&amp; npm run build &amp;&amp; npm run export

    文件build/main.js.zip 将包含您需要的所有内容!

    【讨论】:

    • 我几乎忽略了这个解决方案,因为最初的“包裹”段落并不真正相关,但除此之外这个解决方案很棒;非常简单有效。
    【解决方案7】:

    npm 模块必须捆绑在您的 nodejs 包中并以 zip 格式上传到 AWS Lambda 层,然后您需要如下引用您的模块/js 并使用其中的可用方法。 const mymodule = require('/opt/nodejs/MyLogger');

    【讨论】:

      【解决方案8】:

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

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

      mkdir lambdaFunc
      cd lambdaFunc
      

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

      npm install <your-package-here>
      

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-30
        • 2012-10-15
        • 1970-01-01
        • 2020-11-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多