为 aws lambda 构建节点模块
Posted
技术标签:
【中文标题】为 aws lambda 构建节点模块【英文标题】:Building a node module for aws lambda 【发布时间】:2017-08-14 12:21:14 【问题描述】:我正在尝试在 AWS Lambda 中使用 Sharp 库,但它需要为 lambda 环境编译模块。说明说要创建一个 ec2 实例并在那里编译它 - 但我注意到有一些工具可以帮助解决这个问题,但它们都至少有一年的历史,没有维护。是否有 Serverless 附带的软件包,或者现在被认为是标准方式的软件包?
我已经找到了这些,但它们都在提交后至少一年了
https://github.com/node-hocus-pocus/thaumaturgy
https://github.com/Max-Kolodezniy/aws-lambda-build
https://github.com/tomdale/lambda-packager
也许有一个目录可以让我下载 AWS lambda 的预编译 Sharp 库?
【问题讨论】:
我认为你需要在 Amazon Linux ec2 实例中编译它,除非其他人已经完成并为其他人发布 这个存储库github.com/adieuadieu/serverless-sharp-image/tree/master/lib 声称它有一个带有node_modules/
的压缩包,sharp
需要在 Nodejs 4.3.2 上运行(与 Lambda 环境一样)。
@NikSumeiko 是的,这看起来是一个很好的下载资源,谢谢。一个好的开源项目可能是创建一个存储库,其中包含所有需要它的库的 lambda 特定构建的目录。
【参考方案1】:
我使用 sharp-0.17.3-aws-linux-x64-node-6.10.1.tar.gz tarball 使它工作,它是在运行 Nodejs 6.10.1 的 AWS EC2 实例上创建的。 tarball 包含node_modules/
目录和sharp
特定于Lambda execution environment 的系统二进制文件(libvips 库)。
项目结构
为了避免我的本地 node_modules/
(Mac 上的 Nodejs 7.5)和 tarball(Linux 上的 Nodejs 6.10)内的 node_modules/
之间发生冲突,我在子目录下创建了我的 Lambda 服务。
项目结构如下:
node_modules/
service/
node_modules/ <= sharp-0.17.3-aws-linux-x64-node-6.10.1.tar.gz
utils/
handler.js
package.json <= engines: node 6.10.1
serverless.yml
src/
jasmine.json
package.json
我需要的大多数依赖项都是用于开发和测试目的。这些在根 package.json
文件中维护(还包括 sharp
,但为我的 Nodejs 7.5 环境编译,提供在本地测试图像操作)。
我的service/handler.js
和service/utils/
包含与Lambda function handler 兼容的ES6 源代码——它是从src/
目录转译的。
如果我需要其他依赖项进行生产(除了sharp
),我使用--prefix
选项将它们安装到services/package.json
。但不是aws-lambda
,也不是aws-sdk
——它们是全局安装在Lambda中的,这意味着不需要将它们包含在可部署的.zip
文件中。
npm i -S lodash --prefix services/
它确保安装与Lambda环境兼容的lodash
版本,因为service/package.json
定义了依赖的Nodejs版本:
"private": true,
"engines": "node" : "6.10.1" ,
"dependencies":
...
但是,有一个细微差别——其他生产依赖项不必依赖于环境。如果是这样,它们将无法工作,因为您是从本地机器安装它们的,这不等于 Lambda 的机器。
Lambda 函数部署
由于 Lambda 需要 .zip
存档,我压缩了我的 service/
目录的内容。而且我的 Lambda 函数有效。一切都与 ES6 兼容,sharp
具有 Lambda 环境二进制文件,我的其他生产依赖版本与 Nodejs 6.10.1 相关。
另外,我建议使用Serverless ⚡️(我也使用它)。它极大地简化了 Lambda 函数的开发和部署。
【讨论】:
感谢 Nik 的详细描述!我是一个对 lambda、无服务器框架等比较陌生的人。如果你有时间,你能逐步解释一下如何“使用 tarball”文件吗?我假设您指的是tarball。您是否只需双击 /services 文件夹中的该文件,然后创建 node_modules ?我正在尝试这种方法,然后通过无服务器框架部署它,但到目前为止没有运气。 我的处理程序中的代码在本地运行良好。它只是弄清楚如何正确获取依赖关系,以便它可以在已部署的 lambda 函数上工作。 我让它工作了! :-) 锐利的 API 从 0.16 到 0.17 发生了一些变化,所以在对我的逻辑进行一些调整后,一切正常 @AndriyKulak 很高兴听到它最后对你有用。根据您的 cmets,我了解到我在“项目结构”部分下所指的 tarball 并不明显。因此,我现在添加了一个指向“tarball”参考的链接——它与我的答案的顶部相同。 eghad - 有没有更简单的方法?为什么他们不能修复他们的库,这样就不需要跳过这些障碍?【参考方案2】:尼克的回答绝对帮助我找到了一个可行的解决方案!我要补充的一件事是 serverless-sharp-image 背后的人更新了他们的包,因此 tarball 现在可以与节点 v6.10 一起使用,所以我认为没有理由引用两个不同的节点环境。我在 v6.10 中完成所有操作。
https://github.com/adieuadieu/serverless-sharp-image/tree/master/lib
【讨论】:
你确定你的本地环境等于Lambda execution environment吗?问题是,重要的不仅仅是 Nodejs 版本的平等。如果我没记错的话,libvips
库(sharp
的一部分)区分 Linux、Windows、Mac 机器。 Lambda 在 Linux 上运行。因此,node_modules/sharp
应包含安装在 Linux 上的 libvips
库。
是的。我的文件夹结构与您的@NikSumeiko 非常相似。我只是在 /service 文件夹中使用节点 v6.10,因为 tarball 支持它。唯一让我有点困扰的是我无法在本地环境中轻松迭代。我无法让serverless-offline npm 包使用该目录结构。【参考方案3】:
遇到类似问题并设法通过
为 Linux x64 平台安装二进制文件npm install --arch=x64 --platform=linux --target=8.10.0 sharp
然后像往常一样上传 Lambda 就可以了。 以上适用于 Mac 以及 windows 和详细信息在文档中http://sharp.pixelplumbing.com/en/stable/install/#aws-lambda
【讨论】:
【参考方案4】:对于现在偶然发现这篇文章的任何人。我通过将我的package.json
文件复制到AWS Cloud9 IDE 并简单地运行npm install
来完成此操作。从那里,只需下载node_modules/
文件夹。
【讨论】:
以上是关于为 aws lambda 构建节点模块的主要内容,如果未能解决你的问题,请参考以下文章
使用无服务器和 chrome-aws-lambda 节点包在 AWS Lambda 上找不到 Chrome 二进制文件
使用特定选项或环境变量在AWS lambda中启动NodeJS运行时