首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过无服务器框架部署到AWS Lambda时将文件打包到应用程序包的特定文件夹

通过无服务器框架部署到AWS Lambda时将文件打包到应用程序包的特定文件夹
EN

Stack Overflow用户
提问于 2022-10-07 10:13:38
回答 2查看 444关注 0票数 0

上下文

我正在使用aws-node-typescript示例无服务器框架。我的目标是将普里斯马集成到其中。

到目前为止,我已经:

  1. 使用serverless create在本地创建项目
  2. 建立铁路PostgreSQL数据库
  3. 安装了prisma,运行了prisma init,创建了基本的User模型,并成功地运行了prisma migrate dev
  4. 通过复制现有的users函数创建第二个hello函数
  5. 使用serverless deploy部署该函数
  6. 现在在我的函数中,当我实例化PrismaClient时,我得到一个内部服务器错误,该函数记录这个错误:"ENOENT: no such file or directory, open '/var/task/src/functions/users/schema.prisma'"

我的项目结构如下:

代码语言:javascript
运行
复制
.
├── README.md
├── package-lock.json
├── package.json
├── prisma
│   ├── migrations
│   │   ├── 20221006113352_init
│   │   │   └── migration.sql
│   │   └── migration_lock.toml
│   └── schema.prisma
├── serverless.ts
├── src
│   ├── functions
│   │   ├── hello
│   │   │   ├── handler.ts
│   │   │   ├── index.ts
│   │   │   ├── mock.json
│   │   │   └── schema.ts
│   │   ├── index.ts
│   │   └── users
│   │       ├── handler.ts
│   │       └── index.ts
│   └── libs
│       ├── api-gateway.ts
│       ├── handler-resolver.ts
│       └── lambda.ts
├── tsconfig.json
└── tsconfig.paths.json

另外,下面是users函数的处理程序: ts

代码语言:javascript
运行
复制
import { formatJSONResponse } from '@libs/api-gateway';
import { middyfy } from '@libs/lambda';
import { PrismaClient } from '@prisma/client'

const users = async (event) => {

  console.log(`Instantiating PrismaClient inside handler ...`)
  const prisma = new PrismaClient()

  return formatJSONResponse({
    message: `Hello, ${event.queryStringParameters.name || 'there'} welcome to the exciting Serverless world!`,
    event,
  });
};

export const main = middyfy(users);

出现这个问题是因为为了实例化PrismaClientschema.prisma文件需要成为应用程序包的一部分。具体来说,它需要在/var/task/src/functions/users/中,正如错误消息所指示的那样。

我已经在我的package.patterns文件中调整了serverless.ts选项,如下所示:

代码语言:javascript
运行
复制
package: { individually: true, patterns: ["**/*.prisma"] },

问题

这样,上传到AWS的包在根目录中包含了prisma目录,这是运行sls package后的.serverless文件夹(我在这里解压缩了users.zip以便查看其内容):

代码语言:javascript
运行
复制
.
├── cloudformation-template-create-stack.json
├── cloudformation-template-update-stack.json
├── hello.zip
├── serverless-state.json
├── users
│   ├── prisma
│   │   └── schema.prisma
│   └── src
│       └── functions
│           └── users
│               ├── handler.js
│               └── handler.js.map
└── users.zip

我还可以确认我的AWS Lambda的部署版本具有相同的文件夹结构。

如何使用我的users/prisma/schema.prisma文件中的patterns将该patterns文件移动到users/src/functions/users中?

EN

回答 2

Stack Overflow用户

发布于 2022-10-07 14:57:33

我找到了一个(很难看的)解决方案。如果有人能想到一个更优雅的答案,我仍然非常乐意给你一个正确答案的分数。

"ENOENT: no such file or directory, open '/var/task/src/functions/users/schema.prisma'"误差的求解

为了解决这个问题,我采取了一种非常天真的方法,将schema.prisma文件从prisma目录手动复制到src/functions/users中。下面是我现在拥有的文件结构:

代码语言:javascript
运行
复制
.
├── README.md
├── package-lock.json
├── package.json
├── prisma
│   ├── migrations
│   │   ├── 20221006113352_init
│   │   │   └── migration.sql
│   │   └── migration_lock.toml
│   └── schema.prisma
├── serverless.ts
├── src
│   ├── functions
│   │   ├── hello
│   │   │   ├── handler.ts
│   │   │   ├── index.ts
│   │   │   ├── mock.json
│   │   │   └── schema.ts
│   │   ├── index.ts
│   │   └── users
│   │       ├── schema.prisma
│   │       ├── handler.ts
│   │       └── index.ts
│   └── libs
│       ├── api-gateway.ts
│       ├── handler-resolver.ts
│       └── lambda.ts
├── tsconfig.json
└── tsconfig.paths.json

这显然是解决这个问题的可怕方法,因为我现在在不同的位置上有两个Prisma模式文件,并且必须确保在更改了prisma/schema.prisma中的原始文件以保持它们的同步之后,始终更新prisma/schema.prisma中的一个。

一旦我复制了这个文件并重新部署,schema.prisma文件就在AWS的正确位置上了,错误消失了,PrismaClient可以被实例化了。

然后,我在处理程序中添加了一个简单的Prisma客户端查询:

代码语言:javascript
运行
复制
const users = async (event) => {
  console.log(`Instantiating PrismaClient inside handler ...`)
  const prisma = new PrismaClient()

  const userCount = await prisma.user.count()
  console.log(`There are ${userCount} users in the database`)
  return formatJSONResponse({
    message: `Hello, ${event.queryStringParameters.name || 'there'} welcome to the exciting Serverless world!`,
    event,
  });
};

export const main = middyfy(users);

..。这一次,在查询引擎方面遇到了一个新错误:

代码语言:javascript
运行
复制
Invalid `prisma.user.count()` invocation:


Query engine library for current platform \"rhel-openssl-1.0.x\" could not be found.
You incorrectly pinned it to rhel-openssl-1.0.x

This probably happens, because you built Prisma Client on a different platform.
(Prisma Client looked in \"/var/task/src/functions/users/libquery_engine-rhel-openssl-1.0.x.so.node\")

Searched Locations:

  /var/task/.prisma/client
  /Users/nikolasburk/prisma/talks/2022/serverless-conf-berlin/aws-node-typescript/node_modules/@prisma/client
  /var/task/src/functions
  /var/task/src/functions/users
  /var/task/prisma
  /tmp/prisma-engines
  /var/task/src/functions/users
  
  
  To solve this problem, add the platform \"rhel-openssl-1.0.x\" to the \"binaryTargets\" attribute in the \"generator\" block in the \"schema.prisma\" file:
generator client {
  provider      = \"prisma-client-js\"
  binaryTargets = [\"native\"]
  }

Then run \"prisma generate\" for your changes to take effect.
Read more about deploying Prisma Client: https://pris.ly/d/client-generator

Query engine library for current platform \"rhel-openssl-1.0.x\" could not be found.误差的求解

我非常熟悉Prisma,知道Prisma客户端依赖于专门为Prisma客户端运行的平台构建的查询引擎二进制文件。这可以通过我的Prisma模式中的binaryTargets块上的generator字段进行配置。AWS的目标是rhel-openssl-1.0.x

因此,我相应地调整了schema.prisma文件(在两个位置):

代码语言:javascript
运行
复制
generator client {
  provider = "prisma-client-js"
  binaryTargets = ["native", "rhel-openssl-1.0.x"]
}

之后,我运行npx prisma generate来更新node_modules中生成的Prisma客户机。

然而,这还没有解决错误,问题仍然是Prisma客户端找不到查询引擎二进制。

因此,当schema.prisma文件丢失时,我遵循了与它相同的方法:

  1. 我手动将它复制到src/functions/users中(这次是从它在node_modules/.prisma/libquery_engine-rhel-openssl-1.0.x.so.node中的位置)
  2. 我将新路径添加到我的"**/libquery_engine-rhel-openssl-1.0.x.so.node",:serverless.ts:package:{serverless.ts:true,serverless.ts:“**/*.true”,

在重新部署和测试该功能之后,又发生了另一个错误:

代码语言:javascript
运行
复制
Invalid `prisma.user.count()` invocation:


error: Environment variable not found: DATABASE_URL.
-->  schema.prisma:11
| 
10 |   provider = \"postgresql\"
11 |   url      = env(\"DATABASE_URL\")
| 

Validation Error Count: 1

Environment variable not found: DATABASE_URL.误差的求解

这一次,非常简单,我进入了https://us-east-1.console.aws.amazon.com/lambda/home?region=us-east-1#/functions/aws-node-typescript-dev-users?tab=configure的AWS控制台,通过Console UI添加了一个DATABASE_URL env,指向铁路上的Postgres实例:

票数 2
EN

Stack Overflow用户

发布于 2022-12-01 19:24:17

一个选项是在copy-webpack-plugin中使用webpack并更改应用程序的结构,将所有处理程序放在处理程序文件夹中。

文件夹结构

代码语言:javascript
运行
复制
.
├── handlers/
│   ├── hello.ts
│   └── ...
└── services/
    ├── hello.ts
    └── ...

webpack.config.js

代码语言:javascript
运行
复制
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path");
// const nodeExternals = require("webpack-node-externals");
const CopyPlugin = require("copy-webpack-plugin");
const slsw = require("serverless-webpack");
const { isLocal } = slsw.lib.webpack;

module.exports = {
  target: "node",
  stats: "normal",
  entry: slsw.lib.entries,
  // externals: [nodeExternals()],
  mode: isLocal ? "development" : "production",
  optimization: { concatenateModules: false },
  resolve: { extensions: [".js", ".ts"] },
  output: {
    libraryTarget: "commonjs",
    filename: "[name].js",
    path: path.resolve(__dirname, ".webpack"),
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: "ts-loader",
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "./prisma/schema.prisma",
          to: "handlers/schema.prisma",
        },
        {
          from: "./node_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.node",
          to: "handlers/libquery_engine-rhel-openssl-1.0.x.so.node",
        },
      ],
    }),
  ],
};

如果您需要在组装包之前运行npx生成,您可以使用插件(放在webpack之前):

代码语言:javascript
运行
复制
plugins:
  - serverless-scriptable-plugin
  - serverless-webpack

custom:
  scriptable:
    hooks:
      before:package:createDeploymentArtifacts: npx prisma generate
  webpack:
    includeModules: false

受抚养人:

代码语言:javascript
运行
复制
npm install -D webpack serverless-webpack webpack-node-externals copy-webpack-plugin serverless-scriptable-plugin
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73985623

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档