首页 > 解决方案 > 使用无服务器部署 AWS Lambda 函数在需要外部模块时不会部署

问题描述

我目前正在尝试使用无服务器部署 AWS lambda 函数。如果我不包含任何外部模块,我可以获得正确部署和响应的功能,但是一旦我尝试包含 dynogels 和 Joi:

const dynogels = require("dynogels");
const Joi = require("@hapi/joi");

serverless deploy命令不会通过“打包外部模块”

包括外部模块时的完整输出:

❯ sls deploy
{ addHandler: './addHandler.js' }
Serverless: Bundling with Webpack...
   1 module
Serverless: No external modules needed
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service game-data-service.zip file to S3 (1.9 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..............
Serverless: Stack update finished...
Service Information
service: game-data-service
stage: dev
region: ap-southeast-2
stack: game-data-service-dev
resources: 11
api keys:
  None
endpoints:
  POST - XXXXXXXXXXX/endpoint
functions:
  addData: game-data-service-dev-addData
layers:
  None
Serverless: Updated basepath mapping.
Serverless Domain Manager Summary
Domain Name
  XXXXXXXXXXX.com
Distribution Domain Name
  Target Domain: XXXXXXXXXXX
  Hosted Zone Id: XXXXXXXXXXX
Serverless: Removing old service artifacts from S3...
Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.

包含外部模块时的完整输出:

❯ sls deploy
{ addHandler: './addHandler.js' }
Serverless: Bundling with Webpack...
   3 modules
Serverless: Package lock found - Using locked versions
Serverless: Packing external modules: dynogels@^9.1.0, @hapi/joi@^17.1.0

软件包已安装。我不明白为什么这没有部署。有什么方法可以让我从部署中看到一些错误?--verbose似乎没有提供太多额外的信息。谢谢你的帮助!

编辑 serverless.yml

service: game-data-service

provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  region: ap-southeast-2
  environment:
    SERVICE_NAME: ${self:service}
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:DescribeTable
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
        - dynamodb:BatchGetItem
      Resource: "arn:aws:dynamodb:ap-southeast-2:*:*"
    - Effect: Allow
      Action:
        - codepipeline:StartPipelineExecution
      Resource: "arn:aws:codepipeline:ap-southeast-2:*:*"
    - Effect: Allow
      Action:
        - s3:PutObject
        - s3:PutObjectAcl
      Resource: "arn:aws:s3:::XXXXXXXXXXX-assets-bucket/*"

plugins:
  - serverless-domain-manager
  - serverless-webpack

custom:
  stage: ${opt:stage, self:provider.stage}
  admin_arn: XXXXXXXXXX
  user_arn: XXXXXXXXXXX
  domains:
    prod: XXXXXXXXXXX.com
    staging: XXXXXXXXXXX.com
    dev: XXXXXXXXXXX.com
  webpack:
    webpackConfig: "webpack.config.js"
    includeModules: true # Node modules configuration for packaging
    packagePath: "../package.json"

  customDomain:
    basePath: gameData
    domainName: ${self:custom.domains.${self:custom.stage}}
    stage: "${self:custom.stage}"
    createRoute53Record: true

##############################################################
# Functions
##############################################################

functions:
  addData:
    handler: addHandler.hello
    events:
      - http: POST add

webpack.config.js

const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");
var path = require("path");
function resolve(dir) {
  return path.join(__dirname, dir);
}

console.log(slsw.lib.entries);
module.exports = {
  entry: slsw.lib.entries,
  target: "node",
  // Since 'aws-sdk' is not compatible with webpack,
  // we exclude all node dependencies
  externals: [nodeExternals()],
  resolve: {
    alias: {
      "@": resolve("../lib"),
      "=": resolve("../db")
    }
  },
  optimization: {
    minimize: false
  },
  mode: slsw.lib.webpack.isLocal ? "development" : "production",
  stats: "minimal"
};

addHandler.js

"use strict";

import { success, failure } from "@/response";
// import schema from "=/schema";
// import gameSchema from "=/gameSchema";

// const dynogels = require("dynogels");
// const Joi = require("@hapi/joi");
const cowsay = require("cowsay");


export const hello = (event, context, callback) => {
  console.log("Running ADD");
  console.log(cowsay.say({ text: "Mooodule" }));
  const body = JSON.parse(event.body);

  const table = body["table"];
  const data = body["data"];
  if (body["table"] == null) {
    callback(
      null,
      failure({
        error: "You must provide the table name in the body"
      })
    );
  }
  console.log(`Body recieved for table ${table}:`, data);
  callback(null, success({ message: `Data added to ${table}` }));
  // try {
  //   gameSchema[event.pathParameters.table].create(body, (err, res) => {
  //     if (err) {
  //       callback(null, failure({ error: err }));
  //       return;
  //     }

  //     callback(null, success(res));
  //   });
  //   callback(null, success(res));
  // } catch (err) {
  //   callback(null, failure({ error: err }));
  //   return;
  // }
};

标签: node.jsamazon-web-servicesaws-lambdaserverless-frameworkaws-serverless

解决方案


尝试将Lambda 层用于您的 SAM 应用程序。


推荐阅读