You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CDK中打包TypeScript编写的AppSync解析器?

在CDK中打包AppSync TypeScript解析器的可行方案

AppSync支持用TypeScript编写解析器,但CDK的AppsyncFunction构造仅接受编译后的JS文件,且没有像NodejsLambda那样内置的esbuild打包能力,以下是几种解决思路:

方案一:预编译TS文件(简单直接)

提前把TS解析器编译成JS,再传入CDK:

  • 给解析器目录单独配置tsconfig.json,指定target: "ES2020"(匹配AppSync JS 1.0 runtime)、输出目录等规则。
  • 在package.json里添加编译脚本:"build:resolvers": "tsc --project ./resolvers/tsconfig.json",部署前执行该命令生成JS文件。
  • 在CDK中直接引用编译后的JS路径:
    const resolverFunc = new appsync.AppsyncFunction(this, "MyResolverFunc", {
      name: "my_resolver",
      api,
      dataSource: dynamoDataSource,
      code: appsync.Code.fromAsset(
        path.join(__dirname, "../path/to/compiled/my_resolver.js") // ✅ 指向编译完成的JS文件
      ),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
    });
    

方案二:CDK集成esbuild动态编译

在CDK synth阶段用esbuild自动把TS转成JS,无需手动预编译:

  1. 安装esbuild依赖:npm install esbuild --save-dev
  2. 编写打包工具函数:
    import * as esbuild from 'esbuild';
    import * as path from 'path';
    import * as fs from 'fs-extra';
    import { Construct } from 'constructs';
    
    function buildResolverTs(scope: Construct, tsFilePath: string): appsync.Code {
      const outputDir = path.join(__dirname, '.tmp', 'resolvers');
      const outputJsPath = path.join(outputDir, path.basename(tsFilePath).replace('.ts', '.js'));
    
      // 创建临时输出目录
      fs.ensureDirSync(outputDir);
    
      // esbuild编译TS到JS
      esbuild.buildSync({
        entryPoints: [tsFilePath],
        bundle: true, // 有外部依赖时开启
        platform: 'node',
        target: 'es2020',
        outfile: outputJsPath,
        minify: true, // 可选,压缩代码体积
      });
    
      return appsync.Code.fromAsset(outputDir, {
        fileName: path.basename(outputJsPath),
      });
    }
    
  3. 在CDK中直接传入TS文件路径:
    const resolverFunc = new appsync.AppsyncFunction(this, "MyResolverFunc", {
      name: "my_resolver",
      api,
      dataSource: dynamoDataSource,
      code: buildResolverTs(this, path.join(__dirname, "../path/to/my_resolver.ts")), // ✅ 直接传TS文件
      runtime: appsync.FunctionRuntime.JS_1_0_0,
    });
    

方案三:封装自定义构造复用逻辑

如果有大量TS解析器,可以封装一个类似NodejsLambda的自定义构造,内置打包逻辑:

import * as appsync from 'aws-cdk-lib/aws-appsync';
import * as path from 'path';
import { Construct } from 'constructs';

interface NodejsAppsyncFunctionProps extends Omit<appsync.AppsyncFunctionProps, 'code'> {
  entry: string; // TS解析器文件路径
}

class NodejsAppsyncFunction extends appsync.AppsyncFunction {
  constructor(scope: Construct, id: string, props: NodejsAppsyncFunctionProps) {
    const { entry, ...restProps } = props;
    const outputDir = path.join(__dirname, '.tmp', 'appsync-functions', id);
    const outputJsPath = path.join(outputDir, path.basename(entry).replace('.ts', '.js'));

    // 自动执行esbuild打包
    require('esbuild').buildSync({
      entryPoints: [entry],
      bundle: true,
      platform: 'node',
      target: 'es2020',
      outfile: outputJsPath,
    });

    super(scope, id, {
      ...restProps,
      code: appsync.Code.fromAsset(outputDir, { fileName: path.basename(outputJsPath) }),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
    });
  }
}

使用时直接传入TS路径即可:

const resolverFunc = new NodejsAppsyncFunction(this, "MyResolverFunc", {
  name: "my_resolver",
  api,
  dataSource: dynamoDataSource,
  entry: path.join(__dirname, "../path/to/my_resolver.ts"),
});

内容的提问来源于stack exchange,提问作者fedonev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 22:03:32