如何使用Node.js中的层在AWS SAM模板的lambdas中使用共享代码?

如何使用Node.js中的层在AWS SAM模板的lambdas中使用共享代码?,node.js,aws-lambda,aws-serverless,Node.js,Aws Lambda,Aws Serverless,我们有一个非常简单的用例——我们想与所有的lambda共享代码,而不想使用webpack 我们不能在lambda文件夹中的package.json文件中放置相对路径,因为当您执行sam构建两次时,它会删除共享代码,我不知道为什么 回答要求: 能够在本地进行调试 能够在业务逻辑上运行单元测试(无需在AWS沙箱中运行) 能够在sam本地启动api中运行测试 能够通过sam本地调用调试容器中的代码 sam构建 sam部署 在云中运行AWS Lambda TL;DR 将共享代码放在一个层中 在lam

我们有一个非常简单的用例——我们想与所有的lambda共享代码,而不想使用webpack

我们不能在lambda文件夹中的
package.json
文件中放置相对路径,因为当您执行
sam构建
两次时,它会删除共享代码,我不知道为什么

回答要求:

  • 能够在本地进行调试
  • 能够在业务逻辑上运行单元测试(无需在AWS沙箱中运行)
  • 能够在
    sam本地启动api中运行测试
  • 能够通过
    sam本地调用调试容器中的代码
  • sam构建
  • sam部署
  • 在云中运行AWS Lambda
    • TL;DR

      • 将共享代码放在一个层中
      • 在lambda层中引用共享代码时,如果需要(),请使用三元运算符。检查仅在AWS环境中运行时设置的环境变量。在本例中,我们在SAM模板中添加了一个简短的AWS变量,但是您可以找到AWS自动定义的环境变量,但它们不会那么简短。这使您能够在AWS堆栈之外进行本地调试,从而允许进行测试业务逻辑的非常快速的单元测试
      let math=require(process.env.AWS?'/opt/nodejs/common':'../../layers/layer1/nodejs/common');
      设tuc=require(process.env.AWS?'temp units conv':'../../layers/layer1/nodejs/node_modules/temp units conv');
      
      • 除非在lambda文件夹代码中,否则不需要像那样使用三元运算符

      这里有一个我们认为应该发布的工作示例,这样其他人会比我们轻松得多。 我们认为AWS应该使这更容易


      Gotchas

      此解决方案避免了以下问题。我之所以提到它,是因为它看起来像是一个直截了当的解决方案,我花了很多时间才最终放弃它

      在lambda函数的package.json中添加文件夹引用非常诱人

      //...
      "dependencies": {
          "common":"file:../../layers/layer1/nodejs/common"
      },
      //...
      

      如果这样做,它将在第一次
      sam构建时工作。但是,第二次运行
      sam build
      时,您的共享代码文件夹和所有子目录将被删除。这是因为当sam构建时,它会创建一个.aws sam文件夹。如果该文件夹存在,它将执行npm清理,我认为这就是导致删除共享代码的原因。

      如果在答案中解释解决方案,并根据需要提供相关引用和代码示例,以及链接到git模板,则此答案将更有用。这有助于人们找到答案,告诉人们git回购是否有他们所需要的,并让答案在回购被撤销或链接停止时继续有用:)@MyStackRunnethOver谢谢你的建议。如果你认为我还有什么需要补充的,请告诉我。谢谢你的更新!看起来很棒:)@Brandon谢谢你的回答。我现在可以为我的lambda运行测试了。但是,使用sam local invoke调试容器中的代码仍然无法使用相对路径找到我的层。如果我在本地计算机上手动设置AWS的env,它只有在构建函数后才能工作(在更改代码中的任何内容后,我必须重复执行该操作)。如果我没有每次构建更改,/opt路径或相对路径不起作用。你能帮帮我吗。Thanks@SwopnilDangol我还没有发现开发环境非常棒,因为正如您所说的,每次调用都需要做大量的工作。恐怕我没有太多的东西可以提供给你“这就是你如何拥有令人敬畏的开发体验”的方面。你查看了链接了吗?我在这里给出了一些建议,但这仍然不是一个很棒的开发体验。