繁体   English   中英

Typeorm 不适用于无服务器框架 AWS Lambda

[英]Typeorm doesn't work with Serverless Framework AWS Lambda

好吧,基本上我在尝试serverless deployserverless offline时收到此错误:

PS C:\Users\joaov\Desktop\lambda-ts> serverless offline
Running "serverless" from node_modules
X [ERROR] Could not resolve "mock-aws-s3"

    node_modules/@mapbox/node-pre-gyp/lib/util/s3_setup.js:43:28:
      43 │     const AWSMock = require('mock-aws-s3');
         ╵                             ~~~~~~~~~~~~~

  You can mark the path "mock-aws-s3" as external to exclude it from the bundle, which will remove 
  this error. You can also surround this "require" call with a try/catch block to handle this      
  failure at run-time instead of bundle-time.

X [ERROR] Could not resolve "nock"

    node_modules/@mapbox/node-pre-gyp/lib/util/s3_setup.js:112:23:
      112 │   const nock = require('nock');
          ╵                        ~~~~~~

  You can mark the path "nock" as external to exclude it from the bundle, which will remove this   
  error. You can also surround this "require" call with a try/catch block to handle this failure at
  run-time instead of bundle-time.

X [ERROR] Could not resolve "pg-native"

    node_modules/pg/lib/native/client.js:4:21:
      4 │ var Native = require('pg-native')
        ╵                      ~~~~~~~~~~~

  You can mark the path "pg-native" as external to exclude it from the bundle, which will remove
  this error. You can also surround this "require" call with a try/catch block to handle this   
  failure at run-time instead of bundle-time.

Environment: win32, node 16.14.0, framework 3.14.0 (local) 3.14.0v (global), plugin 6.2.1, SDK 4.3.2
Docs:        docs.serverless.com
Support:     forum.serverless.com
Bugs:        github.com/serverless/serverless/issues

Error:
Error: Build failed with 3 errors:
node_modules/@mapbox/node-pre-gyp/lib/util/s3_setup.js:43:28: ERROR: Could not resolve "mock-aws-s3"   
node_modules/@mapbox/node-pre-gyp/lib/util/s3_setup.js:112:23: ERROR: Could not resolve "nock"
node_modules/pg/lib/native/client.js:4:21: ERROR: Could not resolve "pg-native"
    at failureErrorWithLog (C:\Users\joaov\Desktop\lambda-ts\node_modules\esbuild\lib\main.js:1603:15) 
    at C:\Users\joaov\Desktop\lambda-ts\node_modules\esbuild\lib\main.js:1249:28
    at runOnEndCallbacks (C:\Users\joaov\Desktop\lambda-ts\node_modules\esbuild\lib\main.js:1162:65)   
    at buildResponseToResult (C:\Users\joaov\Desktop\lambda-ts\node_modules\esbuild\lib\main.js:1247:7)
    at C:\Users\joaov\Desktop\lambda-ts\node_modules\esbuild\lib\main.js:1356:14
    at C:\Users\joaov\Desktop\lambda-ts\node_modules\esbuild\lib\main.js:666:9
    at handleIncomingPacket (C:\Users\joaov\Desktop\lambda-ts\node_modules\esbuild\lib\main.js:763:9)
    at Socket.readFromStdout (C:\Users\joaov\Desktop\lambda-ts\node_modules\esbuild\lib\main.js:632:7)
    at Socket.emit (node:events:520:28)
    at Socket.emit (node:domain:475:12)
    at addChunk (node:internal/streams/readable:315:12)
    at readableAddChunk (node:internal/streams/readable:289:9)
    at Socket.Readable.push (node:internal/streams/readable:228:10)
    at Pipe.onStreamRead (node:internal/stream_base_commons:190:23)
PS C:\Users\joaov\Desktop\lambda-ts>

这是代码: package.json依赖项:

"dependencies": {
        "aws-lambda": "^1.0.7",
        "bcrypt": "^5.0.1",
        "dotenv": "^16.0.0",
        "pg": "^8.7.3",
        "reflect-metadata": "^0.1.13",
        "typeorm": "^0.3.6",
        "uuid": "^8.3.2",
        "yup": "^0.32.11"
    },
    "devDependencies": {
        "@serverless/typescript": "^3.8.0",
        "@types/aws-lambda": "^8.10.93",
        "@types/bcrypt": "^5.0.0",
        "@types/node": "^17.0.25",
        "@types/pg": "^8.6.5",
        "@types/uuid": "^8.3.4",
        "esbuild": "^0.14.36",
        "serverless": "^3.14.0",
        "serverless-esbuild": "^1.26.2",
        "serverless-offline": "^8.7.0",
        "ts-node": "^10.7.0",
        "typescript": "^4.6.3"
    }
// src/configs/consts.ts

import {
    AWS_RDS_POSTGRES,
    AWS_RDS_POSTGRES_DB,
    AWS_RDS_POSTGRES_PASSWORD,
    AWS_RDS_POSTGRES_PORT,
    AWS_RDS_POSTGRES_USER
} from '@configs/env_vars';

export const HOST = AWS_RDS_POSTGRES;
export const PORT = AWS_RDS_POSTGRES_PORT;
export const DATABASE = AWS_RDS_POSTGRES_DB;
export const USER = AWS_RDS_POSTGRES_USER;
export const PASSWORD = AWS_RDS_POSTGRES_PASSWORD;
// src/database/config.ts

import { DataSource } from 'typeorm';
import { User } from '@entities/User';
import { HOST, PORT, DATABASE, USER, PASSWORD } from '@configs/consts';

export const connConfig = new DataSource({
    type: 'postgres',
    host: HOST,
    port: Number(PORT),
    database: DATABASE,
    username: USER,
    password: PASSWORD,
    synchronize: false,
    entities: [User],
    migrations: []
});
// src/entities/User.ts

import { BaseEntity, Column, PrimaryGeneratedColumn } from 'typeorm';

export class User extends BaseEntity {
    @PrimaryGeneratedColumn('uuid')
    id: string;

    @Column()
    name: string;

    @Column()
    age: number;

    @Column()
    password: string;
}
// src/lambdas/CreateUser

import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import { handle } from '@services/CreateUser';
import { connConfig } from '@database/config';
import { userSchema } from '@validations/UserSchema';

export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
    try {
        const { body } = event;
        const parsedBody = JSON.parse(body);
        userSchema.isValid(parsedBody).catch(() => {
            throw Error('Invalid user data.');
        });

        const user = await handle(connConfig, parsedBody);

        if (!user) {
            return {
                statusCode: 400,
                body: JSON.stringify({
                    message: "Couldn't create user."
                })
            };
        }

        return {
            statusCode: 200,
            body: JSON.stringify({
                message: 'User created successfully.',
                user
            })
        };
    } catch (error) {
        return {
            statusCode: 500,
            body: JSON.stringify({
                error: (error as Error).message
            })
        };
    }
};
// src/services/CreateUser

import 'reflect-metadata';
import { DataSource } from 'typeorm';
import { hash } from 'bcrypt';
import { User } from '@entities/User';

export const handle = async (dataSource: DataSource, userData: User): Promise<User | undefined> => {
    try {
        await dataSource.initialize();
        const user = new User();
        const { name, password, age } = userData;
        user.name = name;
        user.age = age;

        const hashedPassword = await hash(password, 10);
        user.password = hashedPassword;

        const savedUser = await dataSource.manager.save(user);

        return savedUser;
    } catch (error) {
        throw Error("Couldn't connect to database.");
    }
};
// src/validations/UserSchema

import * as yup from 'yup';

export const userSchema = yup.object().shape({
    name: yup.string().required(),
    age: yup.number().required(),
    password: yup.string().required()
});

我应该怎么做才能解决这个问题并获得有效的 aws-lambda + typeorm?

看起来您正在使用 esbuild 来捆绑您的 lambda? 一些节点模块不喜欢与 esbuild 捆绑在一起,您必须将它们添加为外部模块。 尝试添加到 esbuild 配置:

external:
 - pg-native
 - mock-aws-s3
 - nock

万一它可以帮助其他人 -

我正在使用 AWS SAM,我必须将 Misha 建议的配置添加到template.yaml中。

我将它添加到Metadata部分(在Resources下),如下所示:

Metadata: # Manage esbuild properties
  BuildMethod: esbuild
  BuildProperties:
    Minify: true
    Target: "es2020"
    Sourcemap: true # Enabling source maps will create the required NODE_OPTIONS environment variables on your lambda function during sam build
    EntryPoints:
    - app.ts
    External: # <<------------------- I added this
     - pg-native
     - mock-aws-s3
     - nock

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM