如何在 AWS Lambda 中加载 npm 模块?
How to load npm modules in AWS Lambda?
我使用基于 Web 的编辑器创建了几个 Lambda 函数。到目前为止,一切都很好。我现在想开始使用模块扩展那些模块(例如 Q 代表承诺)。我不知道如何将模块输出到 Lambda,以便我的函数可以使用它们。
我通读了 this,但它似乎涉及从那里设置 EC2 和 运行 Lambda 函数。有一种机制可以在创建函数时上传 zip,但这似乎涉及发送本地开发的函数。由于我在基于 Web 的编辑器中工作,这看起来像是一个奇怪的工作流程。
我如何才能简单地部署一些模块以用于我的 Lambda 函数?
如果不上传 .zip
文件就无法加载 NPM 模块,但实际上您可以将此过程简化为两个快速命令行。
方法如下:
将您的 Lambda 函数文件放在单独的目录中。这是因为您在本地为 Lambda 安装了 npm
包,并且您希望能够隔离和测试您将上传到 Lambda 的内容。
在您在第 1 步中创建的单独的 Lambda 目录中使用 npm install packageName
在本地安装 NPM 包。
确保您的函数在本地 运行ning 时有效:node lambdaFunc.js
(您可以简单地注释掉代码中的两行 export.handler
以调整您的代码运行 本地节点)。
转到 Lambda 的目录并压缩 内容,确保不 包含目录本身。
zip -r lambdaFunc.zip .
如果你安装了aws-cli
,如果你想让你的生活更轻松,我建议你安装,你现在可以输入这个命令:
aws lambda update-function-code --function-name lambdaFunc \
--zip-file fileb://~/path/to/your/lambdaFunc.zip
(上面的 lambdaFunc 部分没有引号,以防你像我一样疑惑)
现在您可以在 Lambda 控制台中单击 test。
我建议为以上两个命令添加一个短别名。这是我拥有的更长的 Lambda 更新命令:
alias up="aws lambda update-function-code --function-name lambdaFunc \
--zip-file fileb://~/path/to/your/lambdaFunc.zip"
需要 .zip
文件才能在 Lambda 中包含 npm 模块。而且您真的不应该将 Lambda 网络编辑器用于任何事情 - 与任何生产代码一样,您应该在本地开发,致力于 git,等等
我的流程:
1) 我的 Lambda 函数通常是大型项目的辅助实用程序,因此我在其中创建了一个 /aws/lambdas 目录来存放它们。
2) 每个单独的 lambda 目录包含一个包含函数代码的 index.js 文件,一个 package.json定义依赖项的文件,以及一个 /node_modules 子目录。 (Lambda 不使用 package.json 文件,只是为了让我们可以在本地 运行 npm install
命令。)
package.json:
{
"name": "my_lambda",
"dependencies": {
"svg2png": "^4.1.1"
}
}
3) 我 .git 忽略所有 node_modules 目录和 .zip 文件,这样 npm 安装和压缩生成的文件就不会弄乱我们的仓库。
.git忽略:
# Ignore node_modules
**/node_modules
# Ignore any zip files
*.zip
4) 我从 运行 npm install
目录中安装模块,develop/test 本地函数。
5) 我将 lambda 目录压缩并通过控制台上传。
(重要提示:不要使用 Finder 中的 Mac 的 'compress' 实用程序来压缩文件!您必须 运行 从目录根目录中的 CLI - 请参阅 )
zip -r ../yourfilename.zip *
注意:
如果您在 Mac 上本地安装节点模块,您可能 运行 会遇到问题,因为某些特定于平台的模块在部署到 Lambda 的基于 Linux 的环境时可能会失败。 (参见 )
解决方案是在从 AMI 启动的 EC2 实例上编译模块,该实例与您使用的 Lambda Node.js 运行时间相对应(请参阅此 Lambda runtimes and their respective AMIs 列表).
希望这对您有所帮助,使用无服务器框架,您可以执行以下操作:
- 将这些内容添加到您的
serverless.yml
文件中:
plugins:
- serverless-webpack
custom:
webpackIncludeModules:
forceInclude:
- <your package name> (for example: node-fetch)
- 然后创建您的 Lambda 函数,通过
serverless deploy
部署它,serverless.yml 中包含的程序包将为您提供。
有关无服务器的更多信息:https://serverless.com/framework/docs/providers/aws/guide/quick-start/
您现在可以使用 Lambda Layers 来解决这个问题。只需添加一个包含您需要的包的层,它就会 运行 完美。
关注这个post:
https://medium.com/@anjanava.biswas/nodejs-runtime-environment-with-aws-lambda-layers-f3914613e20e
npm 模块必须捆绑在您的 nodejs 包中并作为 zip 上传到 AWS Lambda Layers,然后您需要参考下面的 module/js 并使用其中的可用方法。
const mymodule = require('/opt/nodejs/MyLogger');
同样在现在的许多 IDE 中,例如:VSC,您可以安装 AWS 的扩展,然后只需从那里单击上传,无需输入所有这些命令 + 区域。
这是一个例子:
这是一个老问题,但它帮助我找到了一种将新的 Lambda 依赖项添加到 Alexa 技能的非常简单的方法。
像 JohnAllen 的回答一样,您需要在本地计算机上创建一个文件夹,随意命名(随意):
mkdir lambdaFunc
cd lambdaFunc
进入您的文件夹后,使用npm
安装必要的包。对我来说,我需要解析 ISO8601 持续时间(我的命令是 npm install iso8601-duration
):
npm install <your-package-here>
安装后,退出该目录,然后压缩它。在 Alexa Skill 开发人员控制台中打开您的 Alexa Skill,然后 select“导入代码”选项。从这里,您将上传您的 .zip 文件和 select 所有代码:
就是这样!然后你可以像我一样导入代码:
const DateConverter = require('iso8601-duration');
在 parcel 上摆弄了几个小时后,我发现它似乎对浏览器中的 运行ning 做了一些假设(即使我告诉它使用 engine: node
)。
改为:
esbuild
esbuild!
更容易也更快
只需 运行 npm add --save-dev esbuild
,然后将这些脚本添加到您的 package.json
:
{
...
"scripts": {
"build": "esbuild --bundle --minify --platform=node --target=node12 --outdir=build main.js",
"export": "cd build && zip main.js.zip main.js"
},
...
"devDependencies": {
"esbuild": "^0.11.19",
...
}
}
这让我可以使用 aws-sdk
,同时仍然进行 tree-shaking 和缩小,同时仍然能够安装其他依赖项,例如 jest 和 eslint,而无需打包整个 node_modules
文件夹.
要在 CI 中构建包,只需:
npm ci && npm run build && npm run export
文件 build/main.js.zip
将包含您需要的一切!
我使用基于 Web 的编辑器创建了几个 Lambda 函数。到目前为止,一切都很好。我现在想开始使用模块扩展那些模块(例如 Q 代表承诺)。我不知道如何将模块输出到 Lambda,以便我的函数可以使用它们。
我通读了 this,但它似乎涉及从那里设置 EC2 和 运行 Lambda 函数。有一种机制可以在创建函数时上传 zip,但这似乎涉及发送本地开发的函数。由于我在基于 Web 的编辑器中工作,这看起来像是一个奇怪的工作流程。
我如何才能简单地部署一些模块以用于我的 Lambda 函数?
如果不上传 .zip
文件就无法加载 NPM 模块,但实际上您可以将此过程简化为两个快速命令行。
方法如下:
将您的 Lambda 函数文件放在单独的目录中。这是因为您在本地为 Lambda 安装了
npm
包,并且您希望能够隔离和测试您将上传到 Lambda 的内容。在您在第 1 步中创建的单独的 Lambda 目录中使用
npm install packageName
在本地安装 NPM 包。确保您的函数在本地 运行ning 时有效:
node lambdaFunc.js
(您可以简单地注释掉代码中的两行export.handler
以调整您的代码运行 本地节点)。转到 Lambda 的目录并压缩 内容,确保不 包含目录本身。
zip -r lambdaFunc.zip .
如果你安装了
aws-cli
,如果你想让你的生活更轻松,我建议你安装,你现在可以输入这个命令:aws lambda update-function-code --function-name lambdaFunc \ --zip-file fileb://~/path/to/your/lambdaFunc.zip
(上面的 lambdaFunc 部分没有引号,以防你像我一样疑惑)
现在您可以在 Lambda 控制台中单击 test。
我建议为以上两个命令添加一个短别名。这是我拥有的更长的 Lambda 更新命令:
alias up="aws lambda update-function-code --function-name lambdaFunc \ --zip-file fileb://~/path/to/your/lambdaFunc.zip"
需要 .zip
文件才能在 Lambda 中包含 npm 模块。而且您真的不应该将 Lambda 网络编辑器用于任何事情 - 与任何生产代码一样,您应该在本地开发,致力于 git,等等
我的流程:
1) 我的 Lambda 函数通常是大型项目的辅助实用程序,因此我在其中创建了一个 /aws/lambdas 目录来存放它们。
2) 每个单独的 lambda 目录包含一个包含函数代码的 index.js 文件,一个 package.json定义依赖项的文件,以及一个 /node_modules 子目录。 (Lambda 不使用 package.json 文件,只是为了让我们可以在本地 运行 npm install
命令。)
package.json:
{
"name": "my_lambda",
"dependencies": {
"svg2png": "^4.1.1"
}
}
3) 我 .git 忽略所有 node_modules 目录和 .zip 文件,这样 npm 安装和压缩生成的文件就不会弄乱我们的仓库。
.git忽略:
# Ignore node_modules
**/node_modules
# Ignore any zip files
*.zip
4) 我从 运行 npm install
目录中安装模块,develop/test 本地函数。
5) 我将 lambda 目录压缩并通过控制台上传。
(重要提示:不要使用 Finder 中的 Mac 的 'compress' 实用程序来压缩文件!您必须 运行 从目录根目录中的 CLI - 请参阅
zip -r ../yourfilename.zip *
注意:
如果您在 Mac 上本地安装节点模块,您可能 运行 会遇到问题,因为某些特定于平台的模块在部署到 Lambda 的基于 Linux 的环境时可能会失败。 (参见
解决方案是在从 AMI 启动的 EC2 实例上编译模块,该实例与您使用的 Lambda Node.js 运行时间相对应(请参阅此 Lambda runtimes and their respective AMIs 列表).
希望这对您有所帮助,使用无服务器框架,您可以执行以下操作:
- 将这些内容添加到您的
serverless.yml
文件中:
plugins:
- serverless-webpack
custom:
webpackIncludeModules:
forceInclude:
- <your package name> (for example: node-fetch)
- 然后创建您的 Lambda 函数,通过
serverless deploy
部署它,serverless.yml 中包含的程序包将为您提供。
有关无服务器的更多信息:https://serverless.com/framework/docs/providers/aws/guide/quick-start/
您现在可以使用 Lambda Layers 来解决这个问题。只需添加一个包含您需要的包的层,它就会 运行 完美。
关注这个post: https://medium.com/@anjanava.biswas/nodejs-runtime-environment-with-aws-lambda-layers-f3914613e20e
npm 模块必须捆绑在您的 nodejs 包中并作为 zip 上传到 AWS Lambda Layers,然后您需要参考下面的 module/js 并使用其中的可用方法。 const mymodule = require('/opt/nodejs/MyLogger');
同样在现在的许多 IDE 中,例如:VSC,您可以安装 AWS 的扩展,然后只需从那里单击上传,无需输入所有这些命令 + 区域。
这是一个例子:
这是一个老问题,但它帮助我找到了一种将新的 Lambda 依赖项添加到 Alexa 技能的非常简单的方法。
像 JohnAllen 的回答一样,您需要在本地计算机上创建一个文件夹,随意命名(随意):
mkdir lambdaFunc
cd lambdaFunc
进入您的文件夹后,使用npm
安装必要的包。对我来说,我需要解析 ISO8601 持续时间(我的命令是 npm install iso8601-duration
):
npm install <your-package-here>
安装后,退出该目录,然后压缩它。在 Alexa Skill 开发人员控制台中打开您的 Alexa Skill,然后 select“导入代码”选项。从这里,您将上传您的 .zip 文件和 select 所有代码:
就是这样!然后你可以像我一样导入代码:
const DateConverter = require('iso8601-duration');
在 parcel 上摆弄了几个小时后,我发现它似乎对浏览器中的 运行ning 做了一些假设(即使我告诉它使用 engine: node
)。
改为:
esbuild
esbuild!
更容易也更快只需 运行 npm add --save-dev esbuild
,然后将这些脚本添加到您的 package.json
:
{
...
"scripts": {
"build": "esbuild --bundle --minify --platform=node --target=node12 --outdir=build main.js",
"export": "cd build && zip main.js.zip main.js"
},
...
"devDependencies": {
"esbuild": "^0.11.19",
...
}
}
这让我可以使用 aws-sdk
,同时仍然进行 tree-shaking 和缩小,同时仍然能够安装其他依赖项,例如 jest 和 eslint,而无需打包整个 node_modules
文件夹.
要在 CI 中构建包,只需:
npm ci && npm run build && npm run export
文件 build/main.js.zip
将包含您需要的一切!