node.js - 在 NodeJS lambda 中使用自定义层

标签 node.js amazon-web-services serverless layer

尝试将我的层导入我的 lambda 函数时出现错误。
我检查了所有设置和配置,但我不明白为什么在部署和运行我的函数时,我收到来自 AWS 的错误消息,说它找不到 layers层:

{
    "errorType": "Error",
    "errorMessage": "Cannot find module 'layers'\nRequire stack:\n- /var/task/entities/transakWebhookEvent.js\n- /var/task/handler.js\n- /var/task/s_money_movements_api.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js",
    "code": "MODULE_NOT_FOUND",
    "requireStack": [
        "/var/task/entities/transakWebhookEvent.js",
        "/var/task/handler.js",
        "/var/task/s_money_movements_api.js",
        "/var/runtime/UserFunction.js",
        "/var/runtime/index.js"
    ],
    "stack": [
        "Error: Cannot find module 'layers'",
        "Require stack:",
        "- /var/task/entities/transakWebhookEvent.js",
        "- /var/task/handler.js",
        "- /var/task/s_money_movements_api.js",
        "- /var/runtime/UserFunction.js",
        "- /var/runtime/index.js",
        "    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)",
        "    at Module._require.i.require (/var/task/serverless_sdk/index.js:9:73131)",
        "    at require (internal/modules/cjs/helpers.js:74:18)",
        "    at Object.<anonymous> (/var/task/entities/transakWebhookEvent.js:5:20)",
        "    at Module._compile (internal/modules/cjs/loader.js:999:30)",
        "    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)",
        "    at Module.load (internal/modules/cjs/loader.js:863:32)",
        "    at Function.Module._load (internal/modules/cjs/loader.js:708:14)",
        "    at Module.require (internal/modules/cjs/loader.js:887:19)",
        "    at Module._require.i.require (/var/task/serverless_sdk/index.js:9:73397)"
    ]
}
我正在使用无服务器框架来管理我的 lambda 和层的部署。
我的项目是这样设置的:
05-24 07:12PM ~/poc $ ls
README.md  webapp-display  webapp-layers  webapp-money-movements  webapp-signup
我的图层位于具有以下文件夹结构的单独文件夹中:
05-24 07:09PM ~/poc/webapp-layers $ ls
index.js  layers  node_modules  package-lock.json  package.json  serverless.yml
我试图使用我的图层的模块位于此文件夹结构中:
05-24 07:10PM ~/poc/webapp-money-movements $ ls
entities  handler.js  node_modules  package-lock.json  package.json  prettier.config.js  serverless.yml
我的 lambda 模块的 package.json 引用了这样的层:
 {
  "name": "webapp-money-movements",
  "version": "1.0.0",
  "description": "",
  "dependencies": {
    "bcrypt": "^5.0.1",
    "express": "^4.17.1",
    "jsonwebtoken": "^8.5.1",
    "serverless-domain-manager": "^5.1.0",
    "serverless-http": "^2.7.0",
    "serverless-plugin-git-variables": "^5.1.0",
    "uuid": "^8.3.2"
  },
  "devDependencies": {
    "@serverless/eslint-config": "^3.0.0",
    "eslint": "^7.22.0",
    "eslint-config-strongloop": "^2.1.0",
    "eslint-plugin-import": "^2.22.1",
    "git-list-updated": "^1.2.1",
    "prettier": "^2.2.1",
    "layers": "file:../webapp-layers"
  },
  "eslintConfig": {
    "extends": "@serverless/eslint-config/node",
    "root": true
  },
  "scripts": {
    "lint": "eslint  --ignore-path .gitignore .",
    "lint:updated": "pipe-git-updated --ext=js -- eslint --ignore-path .gitignore",
    "prettier-check": "prettier -c --ignore-path .gitignore \"**/*.{css,html,js,json,md,yaml,yml}\"",
    "prettier-check:updated": "pipe-git-updated --ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier -c",
    "prettify": "prettier --write --ignore-path .gitignore \"**/*.{css,html,js,json,md,yaml,yml}\"",
    "prettify:updated": "pipe-git-updated --ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier --write"
  }
}
我的 lambda 函数的 serverless.yml 设置如下:
org: rt
app: poc
service: poc-money-movements

frameworkVersion: '2'

custom:
  tableNameDeposits: 'deposits-table-${self:provider.stage}'
  tableNameWithdrawalRequests: 'withdrawal-request-table-${self:provider.stage}'
  tableFundingAccountTransactions: 'funding-account-transaction-table-${self:provider.stage}'
  defaultRegion: eu-west-2
  [...]
  customStage:
    prod: prod
    staging: staging
    dev: dev
  [...]

plugins:
  - serverless-domain-manager

provider:
  name: aws
  runtime: nodejs12.x
  lambdaHashingVersion: '20201221'
  stage: ${self:custom.customStage.${opt:stage, 'dev'}, self:custom.customStage.dev}
  region: ${opt:region, self:custom.defaultRegion}
  profile: rt-${self:provider.stage}
  apiGateway:
    shouldStartNameWithService: true
  environment:
    WITHDRAWAL_REQUEST_TABLE: ${self:custom.tableNameWithdrawalRequests}
    DEPOSITS_TABLE: ${self:custom.tableNameDeposits}
    FUNDING_ACCOUNT_TRANSACTION: ${self:custom.tableFundingAccountTransactions}
  iam:
    role:
      statements:
        [...]
  

functions:
  money-movements-api:
    handler: handler.handler
    layers:
      - ${cf:poc-layers-${self:provider.stage}.AccountsLambdaLayerQualifiedArn}
    description: All endpoints needed for users to move money
    events:
      - http: ANY /
      - http: 'ANY /{proxy+}'
这是我尝试在我的 nodejs lambda 函数中导入我的层的方法:
// Load the AWS SDK for JS
const AWS = require("aws-sdk");
AWS.config.update({region: 'eu-west-2'});
const jwt = require('jsonwebtoken');
const {accounts} = require("layers");

module.exports.new = async function(body) {
    let order = transakWebhook(body)
    console.log("order: ", order)

    const account = new accounts(order.partnerCustomerId)
[...]
package.json我的图层模块的设置是这样的
{
  "name": "webapp-layers",
  "version": "1.0.0",
  "description": "AWS Lambda Layers for Node.js",
  "main": "index.js",
  "scripts": {
    "compile": "tsc",
    "compile:watch": "npm run compile -- --watch"
  },
  "author": "Remi Tuyaerts",
  "license": "ISC",
  "dependencies": {
    "@middy/core": "^1.5.2",
    "@onfido/api": "^1.5.4",
    "auth0": "2.29.0",
    "awilix": "^4.3.3",
    "aws-sdk": "2.813.0",
    "compose-function": "^3.0.3",
    "date-fns": "2.16.1",
    "dotenv": "8.2.0",
    "ejs": "3.1.5",
    "fs-extra": "^9.1.0",
    "html-pdf": "2.2.0",
    "http-status": "^1.5.0",
    "joi": "17.2.1",
    "jsdom": "16.4.0",
    "knex": "0.21.14",
    "moment": "2.28.0",
    "node-fetch": "2.6.1",
    "nodemailer": "^6.4.17",
    "pg": "^8.4.2",
    "reflect-metadata": "^0.1.13",
    "typeorm": "^0.2.31",
    "winston": "3.3.3"
  },
  "devDependencies": {
    "@types/auth0": "^2.33.2",
    "@types/aws-lambda": "^8.10.72",
    "@types/jsdom": "^16.2.7",
    "@types/node": "^14.14.34",
    "@types/node-fetch": "^2.5.8",
    "@types/nodemailer": "^6.4.1",
    "typescript": "4.2.3"
  }
}
我层的 serverless.yml 设置如下:
org: rt
app: poc
service: poc-layers

provider:
  name: aws
  runtime: nodejs12.x
  lambdaHashingVersion: 20201221
  versionFunctions: false
  stage: ${self:custom.customStage.${opt:stage, 'dev'}, self:custom.customStage.dev}
  region: eu-west-2
  environment:
    STAGE: ${self:provider.stage}

custom:
  tableNameDeposits: 'deposits-table-${self:provider.stage}'
  tableNameWithdrawalRequests: 'withdrawal-request-table-${self:provider.stage}'
  tableFundingAccountTransactions: 'funding-account-transaction-table-${self:provider.stage}'
  customStage:
    prod: prod
    staging: staging
    dev: dev

layers:
  accounts:
    name: accounts
    path: layers/
    retain: true
我的 accounts.js在文件夹 ./webapp-layers/layers/是这样设置的:
const AWS = require("aws-sdk");
AWS.config.update({region: 'eu-west-2'});

const { v4: uuidv4 } = require('uuid');

// Create the DynamoDB Document Client
var dynamodb = new AWS.DynamoDB.DocumentClient();
var tableName = process.env.DEPOSITS_TABLE;

class accounts {
    constructor(userId) {
        this.userId = userId
    }
    
[...]

module.exports = { accounts };
我还在 index.js 中导出我的图层在 ./webapp-layers/ 的根像这样:
"use strict";
const accounts = require("./layers/accounts");
exports.accounts = accounts;

最佳答案

首先,关于层文件夹结构,你所有的共享文件都必须存放在下。 nodejs 文件夹。这意味着,您的 layer看起来像这样:
05-24 07:09PM ~/poc/webapp-layers $ ls
index.js 层 node_modules package-lock.json package.json serverless.yml

~/poc/webapp-layers $ tree
...
layers/
   nodejs/
      accounts/
         index.js
...

但是,使用上述结构,您必须更新 lambda 函数以要求 accounts模块
const accounts = require("/opt/nodejs/accounts");
如果你想使用
const { accounts } = require("layers");
结构应该是:
~/poc/webapp-layers $ tree
...
layers/
   nodejs/
      node_modules/   <---------------
          layer/
             index.js
      accounts/
         index.js
layer/index.js只是再导出accounts模块
"use strict";
const accounts = require("../accounts");
exports.accounts = accounts;

关于node.js - 在 NodeJS lambda 中使用自定义层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67677392/

相关文章:

javascript - Node js for 循环定时器

linux - 如何从另一台 PC 进入 AWS 实例

amazon-web-services - 直接从 url 上传文件到 S3 Bucket

node.js - 我得到 - 错误 : Entry not found in cache - during sls deploy

javascript - 使用 Axios 克服 Pending Promise 并在 Node.js 中完成 JSON 构建

node.js - 无法在 Apple Silicon M1 上安装 npm

amazon-web-services - 使用 AWS 基础设施为静态网站实现数据搜索系统的建议

serverless - 无服务器云原生也是吗?

azure - 无法使用 Azure Function Core Tools 在本地运行 cosmosDB 触发器

linux - 是否可以在没有 GUI 的情况下从控制台运行 node-webkit