尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Serverless DApp 本地环境:模拟链、密钥与部署配置

Serverless DApp 本地环境:模拟链、密钥与部署配置 Serverless DApp 本地环境模拟链、密钥与部署配置Serverless DApp 的本地环境至少要模拟链状态、函数运行时和密钥注入。固定区块或测试账户后部署脚本才有可重复输入。真实私钥不要写进仓库或示例配置。1. 本地拟真环境与流水线架构设计本地拟真与 CI/CD 自动化流水线拓扑如下2. 工程实现本地脚手架与 CI/CD 流水线下面的代码展示如何基于 Serverless Framework、TypeScript 和 GitHub Actions 构建可在本地验证的脚手架与自动化部署流水线。2.1 Serverless 声明配置 (serverless.yml)service: enterprise-api-service frameworkVersion: 3 provider: name: aws runtime: nodejs20.x stage: ${opt:stage, dev} region: ap-northeast-1 memorySize: 256 timeout: 10 environment: NODE_ENV: ${self:provider.stage} DYNAMODB_TABLE: ${self:service}-table-${self:provider.stage} iam: role: statements: - Effect: Allow Action: - dynamodb:Query - dynamodb:GetItem - dynamodb:PutItem Resource: arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE} plugins: - serverless-plugin-typescript - serverless-offline functions: apiHandler: handler: src/handler.main events: - http: path: /v1/data method: post cors: true - http: path: /v1/health method: get cors: true custom: serverless-offline: httpPort: 4000 websocketPort: 4001 lambdaPort: 40022.2 本地可单体测试的 Handler (src/handler.ts)import { APIGatewayProxyEvent, APIGatewayProxyResult } from aws-lambda; import { z } from zod; const requestSchema z.object({ action: z.enum([CREATE, QUERY]), payload: z.record(z.unknown()), }); export const main async (event: APIGatewayProxyEvent): PromiseAPIGatewayProxyResult { console.log([Serverless Event] RequestId: ${event.requestContext.requestId}, Path: ${event.path}); // 1. 路由分支处理 if (event.path /v1/health) { return createResponse(200, { status: UP, timestamp: new Date().toISOString() }); } try { if (!event.body) { return createResponse(400, { error: Missing request body }); } const parsedBody JSON.parse(event.body); const validatedData requestSchema.parse(parsedBody); // 2. 模拟本地与云端兼容的数据持久化逻辑 const result await processDataAction(validatedData.action, validatedData.payload); return createResponse(200, { success: true, data: result }); } catch (err: any) { if (err instanceof z.ZodError) { return createResponse(400, { error: Validation Failed, details: err.errors }); } console.error([Handler Error]:, err); return createResponse(500, { error: Internal Server Error }); } }; async function processDataAction(action: string, payload: Recordstring, unknown) { // 在本地 Serverless Offline 下读取环境变量 const tableName process.env.DYNAMODB_TABLE || local-mock-table; return { processed: true, action, tableName, timestamp: Date.now(), }; } function createResponse(statusCode: number, body: object): APIGatewayProxyResult { return { statusCode, headers: { Content-Type: application/json, Access-Control-Allow-Origin: *, Access-Control-Allow-Credentials: true, }, body: JSON.stringify(body), }; }2.3 GitHub Actions 零失败发布流水线 (.github/workflows/deploy.yml)name: Serverless CI/CD Pipeline on: push: branches: [ main, staging ] jobs: test-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkoutv4 - name: Setup Node.js Environment uses: actions/setup-nodev4 with: node-version: 20 cache: npm - name: Install Dependencies run: npm ci - name: Run Type Check Linter run: | npx tsc --noEmit npm run lint - name: Run Local Serverless Unit Tests run: npm run test - name: Deploy to AWS Serverless env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | STAGE_NAME${{ github.ref refs/heads/main prod || staging }} npx serverless deploy --stage $STAGE_NAME3. 本地一次跑通的工程守则为了减少本地与云端部署差异研发阶段可以遵循以下规则并在 CI 中验证关键配置不要让 Handler 隐式依赖某个云环境用dotenv-flow或serverless-offline注入配置并在测试中替换外部依赖。注入环境变量本身不能证明函数无状态还需检查全局缓存与文件写入。坚持 Handler 层与底层业务逻辑解耦不要把所有数据库查询、第三方 API 调用都写在event监听函数里。将业务逻辑抽象为纯 Node.js 服务层单体单元测试Unit Test直接测试服务层API 级测试交由 Serverless Offline。在本地用 Docker 模拟持久化依赖对于 S3 存储桶或 DynamoDB/Redis 依赖本地使用 Docker Compose 启动 LocalStack。本地模拟器调通后切换到云端环境只需要修改 DNS 配置或环境变量。
返回列表