【问题标题】:Including local dependencies in deployment to lambda在部署到 lambda 时包括本地依赖项
【发布时间】:2016-02-04 08:17:13
【问题描述】:

我有一个包含几个“微服务”的存储库,我将它们上传到 AWS 的 Lambda。此外,我还有一些共享库,我想在发送到 AWS 时打包它们。

因此我的目录结构如下:

/micro-service-1
    /dist
        package.json
        index.js
/micro-service-2
    /dist
        package.json
        index.js
/shared-component-1
    /dist
        package.json
        component-name-1.js
/shared-component-2
    /dist
        package.json
        component-name-2.js

基本部署利用了方便的 node-lambda npm 模块,但是当我使用如下语句引用本地共享组件时:

var sharedService = require('../../shared-component-1/dist/index');

这与node-lambda run 命令配合得很好,但node-lambda deploy 放弃了这个本地依赖。可能是有道理的,因为我在依赖项中的“根”目录下面,所以我想也许我会利用 gulp 来完成这项工作,但我对它很陌生,所以我可能是做一些愚蠢的事情。我的策略是:

  • gulp deploy 依赖于一个local-deps 任务
  • local-deps 任务将:
    • npm build --production 到目录
    • 然后将这个目录通过管道传递给/local目录下的微服务
    • 清理共享中的安装
  • 然后我会像这样引用所有共享组件:

    var sharedService = require('local/component-name-1');
    

希望这能实现我想要实现的目标。这个策略有意义吗?我应该考虑一种更简单的方法吗?有人在“gulp speak”中有类似的例子吗?

【问题讨论】:

  • 我也遇到过这个问题。如果 node-lambda 包含它会很好。否则,gulp 任务似乎是要做的事情,但感觉非常“古怪”和令人费解。当我决定我要做什么时会在这里评论! :)

标签: node.js npm gulp aws-lambda


【解决方案1】:

在使用无服务器时,我们遇到了类似的问题,需要在 AWS Lambda 之间共享代码。最初我们习惯于在每个微服务之间复制代码,但后来一如既往地变得难以管理。

由于是在 Windows 环境下开发的,所以我们不能选择使用符号链接。

然后我们想出了一个解决方案,使用共享文件夹来保存本地依赖项,并使用自定义编写的 gulp 任务将这些依赖项复制到每个微服务端点,以便可以像 npm 包一样需要依赖项。

我们做出的决定之一是不保留两个位置来定义微服务的依赖项,因此我们使用相同的 package.json 来定义本地共享依赖项,其中 gulp 任务传递此文件并相应地复制共享依赖项使用单个命令安装 npm 依赖项。

后来我们将代码开源为 npm 模块 serverless-dependency-installgulp-dependency-install

【讨论】:

    【解决方案2】:

    我有一个答案! :D

    TL;DR - 使用 npm link 链接在公共组件和依赖组件之间创建符号链接。

    所以,我有一个只有两个模块的项目:

    - main-module
    - referenced-module
    

    每一个都是一个节点模块。如果我将cd 运行到referenced-module 并运行npm link,然后将cd 运行到main-modulenpm link referenced-module,npm 将“安装”我的referenced-module 到我的main-module 并将其存储在我的node_modules文件夹。注意:运行第二个npm link 时,项目名称是您在package.json 中找到的名称,而不是目录名称(参见npm link 文档,之前已链接)。

    现在,在我的main-module 中,我需要做的就是var test = require('referenced-module'),我可以尽情地使用它。请务必从您的referenced-modulemodule.exports 您的代码!

    现在,当您压缩 main-module 以将其部署到 AWS Lambda 时,链接已解析,并且 real 模块已放置到位!我已经对此进行了测试,并且它可以工作,虽然还没有使用 node-lambda,但我不明白为什么这应该是一个问题(除非它对包恢复有不同的作用)。

    这种方法的另一个好处是,我对referenced-module 所做的任何更改都会在开发过程中由我的main-module 自动获取,因此我不必运行任何 gulp 任务或任何同步它们的东西。

    我发现这是一个非常好的、干净的解决方案,我能够在几分钟内让它工作。如果我上面描述的任何内容都没有任何意义(因为我自己刚刚发现了这个解决方案!),请发表评论,我会尽力为你澄清。

    2016 年 2 月更新

    根据您的要求和应用程序的大小,可能有一个有趣的替代方案可以比使用符号链接更优雅地解决此问题。看看Serverless。这是构建无服务器应用程序的一种非常简洁的方式,并且包括有用的功能,例如能够分配触发您正在编写的 Lambda 函数的 API Gateway 端点。它甚至允许您编写 CloudFormation 配置脚本,因此如果您有其他资源要部署,那么您可以在此处进行。需要“beta”或“prod”阶段?这也可以为你做到。我已经使用它一个多星期了,虽然需要做一些设置并且事情并不总是如您所愿,但它非常灵活并且支持社区很好!

    【讨论】:

    • 有趣的方法,我明天试试。缺乏同步——同时使两个项目更加耦合——对于我当前的大多数用例来说会很好。
    • 下班回家后,我将其放入自己的项目中,并且运行良好。我在 PC 上工作,家里有 Mac,所以它是跨平台的。此外,一旦您从要分发的模块建立了初始链接,您就可以多次使用“安装”命令。只需更改要安装它的每个模块目录并再次运行该命令即可。 :) 祝你好运!
    • 真的很喜欢这个解决方案,因为这两个微服务都在进行主动开发。当依赖项在开发中变慢时,您可以简单地 npm unlink 然后将依赖项指向一个 repo。
    • 啊,太好了,我自己还没走那么远。我很高兴这存在,因为必须创建一些 gulp 任务来复制或复制内容将是可怕的,并且在我的工作流程中是一个真正的扳手。
    • 下次我这样做时,我将完全避免嵌套结构。只是增加了不必要的复杂性,当每个服务都是自己的存储库时,您的解决方案将正常工作。干净多了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 2014-08-20
    • 2021-01-14
    • 1970-01-01
    • 2020-02-16
    • 2018-07-19
    • 2021-09-22
    相关资源
    最近更新 更多