借助 AWS SAM(针对 NodeJS 配置),如何使用从 Lambda 层目录导入的需要自己的 npm 软件包的函数?

With AWS SAM (configured for NodeJS) how can I use my own functions, imported from a Lambda layer directory, that requires it's own npm packages?

提问人:mepley 提问时间:10/7/2023 更新时间:10/7/2023 访问量:76

问:

我有一个 lambda 处理程序文件,我在其中导入一个自定义函数,我是这样编写的:index.mjs

import { myCustomFunc } from './opt/my-layer/myCustomFunc.mjs' // no clue where to actually import from due to conflicting docs

export async function handler() {
  myCustomFunc();
}

./layers/my-layer/myCustomFunc.mjs --> ./opt/myCustomFunc.mjs(在最终版本中) sam build

import { joi } from 'joi'; // this is an npm package

export function myCustomFunc() {
  console.log(joi.version()); // should log '17.11.0'
}

我在本地运行(运行 Docker),但没有看到记录的“joi”版本,而是出现错误:sam buildsam local invoke MyLambdaName -my-event.json

"Cannot find module '/var/opt/nodejs/node_modules/joi' imported from ..."

我对 Lambda 函数的配置引用了两层,其中一层用于 nodejs 包,另一层用于我的 .但是我尝试了许多不同的文件排列方式,包括将每个文件(节点.js和我的自定义函数)放在层中,并将整个node_modules文件夹放在根目录下,但这并没有什么区别。在我的自定义函数中从未找到该包。template.yaml!Reflayers/nodejsmy-layermyCustomFunc.mjslayers/nodejslayers/shared

有没有人能够将 AWS SAM 配置为使用导入节点包的自定义函数的层(本地和云中)调用 lambda 函数?你能分享一下你是怎么做到的吗,因为我已经坚持了两天了。

我希望使用 AWS SAM(具有对 npm 包的完全访问权限)在本地构建和测试函数的简单性,快速迭代,并且只有在测试通过时才推送到云。我不想创建 .zip 层文件、上传 zip、调用云中的 lambda 只是为了查看我的层是否配置正确;对于一个更大的项目来说,这是荒谬的,而不是我问题的答案。

谢谢

节点 .js 亚马逊网络服务 aws-lambda aws-sam aws-lambda-layers

评论


答:

0赞 Quassnoi 10/7/2023 #1

请注意 SAM 如何转换路径,但 Lambda 的工作原理如下:

  1. 图层的目录挂载到/opt
  2. NodeJS 运行时已将NODE_PATH设置为/opt/nodejs/$NODE_VERSION/node_modules/:/opt/nodejs/node_modules:$LAMBDA_RUNTIME_DIR/node_modules

这意味着,要从图层导入某些内容,您可以选择:

  1. 按绝对路径导入:

    import { myCustomFunc } from '/opt/…/myCustomFunc.mjs'
    

    这样,您可以将其放置在图层中的任意位置,只需在导入中将其添加到其路径之前即可/opt

  2. 把它做成一个有结构的适当模块,放在下面nodejs/node_modules

    // /nodejs/node_modules/myCustomFunc/index.js (+package.json and all the jazz)
    
    import { myCustomFunc } from 'myCustomFunc'
    

一旦运行 lambda 的节点(从内部)导入并执行 中的代码,它将开始查找 .$LAMBDA_RUNTIME_DIRmyCustomFuncjoi

它不是一个文件,因此您没有其他选择将其放置在图层中。/nodejs/node_modules/joi

从技术上讲,您可以将其放在使用此层的每个 lambda 中,它会起作用,但正如您可能猜到的那样,这不是一个很好的解决方案。node_modules