AWS Lambda执行环境预装了哪些NPM模块?

Which NPM modules are preinstalled in AWS Lambda execution environment?

最近发现AWS Lambda nodejs8.10预装了aws-sdkNPM模块。我在互联网上找不到任何关于它的信息。

AWS Lambda 中预装了哪些其他 node.js 模块?

仅预装了 aws-sdk 软件包。

其余全部从"node_modules"目录加载..

您可以在这里找到相关信息:

https://docs.aws.amazon.com/lambda/latest/dg/nodejs-create-deployment-pkg.html

我已经使用了 "https" 和 "url" 包,所以至少这些是预安装的。有相当多的标准 node.js 模块需要原生层。

显然 AWS 模块在那里,用于与 AWS 服务通信。例如,我使用过 SQS。

还没有尝试 "fs",但是因为它需要一个本机层,并且是您可能想要做的事情(例如将内容持久化到 /tmp)我假设它在那里。

某处应该有一个列表。但我找不到一个。猜猜你只需要尝试,如果 requires 失败,那么你需要在 node_modules 中放置一个模块,然后查看它是否需要依赖项。

我找不到官方列表,所以我写了一个脚本来创建列表。

我在我的 Lambda 中安装了一些 其他库,它们是(不包括 built-in nodejs 模块,它们当然也可用):

'aws-sdk',      <-- preinstalled by AWS
'awslambda',
'base64-js',
'dynamodb-doc',
'ieee754',
'imagemagick',
'isarray',
'jmespath',
'lodash',
'sax',
'uuid',
'xml2js',
'xmlbuilder'

生成此列表的代码:

function flatten(arrayOfArrays) {
    return Array.prototype.concat.apply([], arrayOfArrays)
}

function onlyUnique(value, index, self) {
    return self.indexOf(value) === index;
}

function extPackageNames(node) {
    if (!node.children) return [];
    const arrayOfArrays = node.children.map(c => [c.name].concat(extPackageNames(c)))
    const result = flatten(arrayOfArrays)
    return result
}

exports.handler = async (event) => {
    const rpt = require("read-package-tree")
    const module = require("module")

    const pathArg = process.env.NODE_PATH
    const allPaths = pathArg.split(":")

    // '/var/task' is this package on lambda
    const externalPaths = allPaths.filter(p => p !== "/var/task")

    // read all package data
    const ps = externalPaths.map((path) => rpt(path).catch(err => err))
    const rpts = await Promise.all(ps).catch(err => err)

    // extract the information we need
    const packagesPerPath = rpts.map(extPackageNames)
    const countPerPath = packagesPerPath.map(arr => arr.length)
    const packages = flatten(packagesPerPath)

    // remove duplicates
    const uniquePackages = packages.filter(onlyUnique)

    // remove node.js built-in modules
    const uniqueCustomPackages = uniquePackages.filter(p => !module.builtinModules.includes(p))

    const result = {
        node_path: pathArg,
        paths: externalPaths.map((e, i) => [e, countPerPath[i]]),
        uniqueCustomPackages
    }

    console.log(result)

    const response = {
        statusCode: 200,
        body: JSON.stringify(result)
    };
    return response;
};

要 运行 在 lambda 上使用此文件,您需要将其与包含 read-package-tree.

node_modules 文件夹一起压缩

不幸的是,文档似乎对此并不十分具体,但您可以自己获取他们的 docker 图片并 bash 检查它们:

docker run --rm -it --entrypoint /bin/bash amazon/aws-lambda-nodejs:14

DockerfileENTRYPOINT ["/lambda-entrypoint.sh"] 并且通过检查该文件我能够确定它通过 /var/runtime/bootstrap.

运行 Node

/var/runtime/bootstrap 将各种目录添加到 NODE_PATH,可以从中加载模块:

if [ -z "$NODE_PATH" ];
then
  nodejs_mods="/opt/nodejs/node_modules"
  nodejs14_mods="/opt/nodejs/node14/node_modules"
  runtime_mods="/var/runtime/node_modules"
  task="/var/runtime:/var/task"
  export NODE_PATH="$nodejs14_mods:$nodejs_mods:$runtime_mods:$task"
fi

但是 /opt/nodejs 不存在于图像中,/var/task 是 Lambda 放置您的自定义代码的地方。

所以 /var/runtime/node_modules 是我们需要检查的唯一目录:

bash-4.2# cd /var/runtime
bash-4.2# npm ls
/var/runtime
└─┬ aws-sdk@2.1001.0
  ├── buffer@4.9.2 extraneous
  ├── events@1.1.1 extraneous
  ├── ieee754@1.1.13 extraneous
  ├── jmespath@0.15.0 extraneous
  ├── querystring@0.2.0 extraneous
  ├── sax@1.2.1 extraneous
  ├── url@0.10.3 extraneous
  ├── uuid@3.3.2 extraneous
  └── xml2js@0.4.19 extraneous

如您所见,仅预装了 aws-sdk。但是你可以使用这个过程来确定他们是否在他们的 Node.js 运行时的未来版本中添加了更多预安装的依赖。