在部署到 lambda 时包括本地依赖项
Including local dependencies in deployment to lambda
我有一个包含多个 "micro-services" 的存储库,我上传到 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
删除了这个本地依赖项。可能是有道理的,因为我要在依赖项中的 "root" 目录下面,所以我想也许我会利用 gulp 来完成这项工作,但我对它很陌生,所以我可能在做一些愚蠢的事情。我的策略是:
gulp deploy
依赖 local-deps 任务
- local-deps 任务将:
npm build --production
到目录
- 然后将此目录通过管道传输到
/local
目录下的微服务
- 清理共享中的安装
然后我会像这样引用所有共享组件:
var sharedService = require('local/component-name-1');
希望这能实现我想要实现的目标。这个策略有意义吗?我应该考虑更简单的方法吗?在 "gulp speak" 中有人有任何类似的例子吗?
我有一个答案! :D
TL;DR - 使用 npm link
到 link 在公共组件和依赖组件之间创建符号 link。
所以,我有一个只有两个模块的项目:
- main-module
- referenced-module
其中每一个都是一个节点模块。如果我 cd
变成 referenced-module
和 运行 npm link
,那么 cd
变成 main-module
和 npm link referenced-module
,npm 会 'install' 我的 referenced-module
到我的 main-module
并将其存储在我的 node_modules
文件夹中。注意:当 运行 设置第二个 npm link
时,项目名称是您在 package.json
中找到的项目名称,而不是目录名称(请参阅 npm link
文档,之前 linked).
现在,在我的 main-module
中,我需要做的就是 var test = require('referenced-module')
,我可以尽情使用它。请务必 module.exports
来自 referenced-module
!
的代码
现在,当您压缩 main-module
将其部署到 AWS Lambda 时,link 被解析并且 real 模块被放入它们的地方!我已经对此进行了测试并且它可以工作,虽然还不能与 node-lambda
一起使用,但我不明白为什么这应该是一个问题(除非它对包恢复做了一些不同的事情)。
这种方法的优点还在于,我对 referenced-module
所做的任何更改都会在开发过程中自动被我的 main-module
接受,因此我不必 运行 任何 gulp 任务或任何同步它们的东西。
我发现这是一个非常好的、干净的解决方案,我能够在几分钟内让它工作。如果我上面描述的任何内容没有任何意义(因为我自己才刚刚发现这个解决方案!),请发表评论,我会尽力为您澄清。
2016 年 2 月更新
根据您的要求和您的应用程序的大小,可能有一个有趣的替代方案可以比使用 symlinking 更优雅地解决这个问题。看看 Serverless。这是构建无服务器应用程序的一种非常巧妙的方法,包括一些有用的功能,例如能够分配 API 网关端点来触发您正在编写的 Lambda 函数。它甚至允许您编写 CloudFormation 配置脚本,因此如果您有其他资源要部署,那么您可以在此处执行此操作。需要 'beta' 或 'prod' 舞台?这也可以为你做。我已经使用了一个多星期,虽然需要进行一些设置并且事情并不总是像您想要的那样清晰,但它非常灵活并且支持社区很好!
在使用无服务器时,我们遇到了类似的问题,需要在 AWS Lambda 之间共享代码。最初我们习惯于跨每个微服务复制代码,但后来一如既往地变得难以管理。
由于在 Windows 环境中完成开发,使用符号链接对我们来说不是一个选择。
然后我们想出了一个解决方案,使用共享文件夹来保存本地依赖项,并使用自定义编写的 gulp 任务跨每个微服务端点复制这些依赖项,以便需要依赖项类似于 npm 包。
我们做出的一个决定是不保留两个地方来定义微服务的依赖关系,所以我们使用相同的package.json来定义本地共享依赖关系,其中gulp任务通过这个文件并相应地复制共享依赖项,同时使用单个命令安装 npm 依赖项。
后来我们将代码开源为 npm 模块serverless-dependency-install and gulp-dependency-install。
我有一个包含多个 "micro-services" 的存储库,我上传到 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
删除了这个本地依赖项。可能是有道理的,因为我要在依赖项中的 "root" 目录下面,所以我想也许我会利用 gulp 来完成这项工作,但我对它很陌生,所以我可能在做一些愚蠢的事情。我的策略是:
gulp deploy
依赖 local-deps 任务- local-deps 任务将:
npm build --production
到目录- 然后将此目录通过管道传输到
/local
目录下的微服务 - 清理共享中的安装
然后我会像这样引用所有共享组件:
var sharedService = require('local/component-name-1');
希望这能实现我想要实现的目标。这个策略有意义吗?我应该考虑更简单的方法吗?在 "gulp speak" 中有人有任何类似的例子吗?
我有一个答案! :D
TL;DR - 使用 npm link
到 link 在公共组件和依赖组件之间创建符号 link。
所以,我有一个只有两个模块的项目:
- main-module
- referenced-module
其中每一个都是一个节点模块。如果我 cd
变成 referenced-module
和 运行 npm link
,那么 cd
变成 main-module
和 npm link referenced-module
,npm 会 'install' 我的 referenced-module
到我的 main-module
并将其存储在我的 node_modules
文件夹中。注意:当 运行 设置第二个 npm link
时,项目名称是您在 package.json
中找到的项目名称,而不是目录名称(请参阅 npm link
文档,之前 linked).
现在,在我的 main-module
中,我需要做的就是 var test = require('referenced-module')
,我可以尽情使用它。请务必 module.exports
来自 referenced-module
!
现在,当您压缩 main-module
将其部署到 AWS Lambda 时,link 被解析并且 real 模块被放入它们的地方!我已经对此进行了测试并且它可以工作,虽然还不能与 node-lambda
一起使用,但我不明白为什么这应该是一个问题(除非它对包恢复做了一些不同的事情)。
这种方法的优点还在于,我对 referenced-module
所做的任何更改都会在开发过程中自动被我的 main-module
接受,因此我不必 运行 任何 gulp 任务或任何同步它们的东西。
我发现这是一个非常好的、干净的解决方案,我能够在几分钟内让它工作。如果我上面描述的任何内容没有任何意义(因为我自己才刚刚发现这个解决方案!),请发表评论,我会尽力为您澄清。
2016 年 2 月更新
根据您的要求和您的应用程序的大小,可能有一个有趣的替代方案可以比使用 symlinking 更优雅地解决这个问题。看看 Serverless。这是构建无服务器应用程序的一种非常巧妙的方法,包括一些有用的功能,例如能够分配 API 网关端点来触发您正在编写的 Lambda 函数。它甚至允许您编写 CloudFormation 配置脚本,因此如果您有其他资源要部署,那么您可以在此处执行此操作。需要 'beta' 或 'prod' 舞台?这也可以为你做。我已经使用了一个多星期,虽然需要进行一些设置并且事情并不总是像您想要的那样清晰,但它非常灵活并且支持社区很好!
在使用无服务器时,我们遇到了类似的问题,需要在 AWS Lambda 之间共享代码。最初我们习惯于跨每个微服务复制代码,但后来一如既往地变得难以管理。
由于在 Windows 环境中完成开发,使用符号链接对我们来说不是一个选择。
然后我们想出了一个解决方案,使用共享文件夹来保存本地依赖项,并使用自定义编写的 gulp 任务跨每个微服务端点复制这些依赖项,以便需要依赖项类似于 npm 包。
我们做出的一个决定是不保留两个地方来定义微服务的依赖关系,所以我们使用相同的package.json来定义本地共享依赖关系,其中gulp任务通过这个文件并相应地复制共享依赖项,同时使用单个命令安装 npm 依赖项。
后来我们将代码开源为 npm 模块serverless-dependency-install and gulp-dependency-install。