为 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.jsservice/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运行时

Lambda AWS 不调用节点 mysql 回调

部署到 AWS lambda 时找不到模块 ./dist/server

AWS Lambda 函数能否通过 *** 调用终端节点?

如何使用依赖项创建AWS nodejs lambda函数