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

从Serverless 3迁移至SST时GraphqlLoaderPlugin报错,求正确加载语法

Serverless 3迁移至SST时esbuild插件加载错误解决方法

问题背景

正在将基于Serverless 3的应用迁移到SST,原Serverless配置中的esbuild自定义段如下:

custom:
  esbuild:
    bundle: true
    minify: false
    plugins: ./esbuild-plugins.js
    sourcemap: true
    target: es2022

对应的esbuild-plugins.js插件文件内容:

const { default: graphqlLoaderPlugin } = require("@luckycatfactory/esbuild-graphql-loader");
const { nodeExternalsPlugin } = require("esbuild-node-externals");
const fs = require("fs-extra");
const path = require("path");

const copyPlugin = ({ from, to }) => {
    return {
        name: "copy",
        setup(build) {
            const target = build.initialOptions.outfile
                ? path.dirname(build.initialOptions.outfile)
                : path.resolve(build.initialOptions.outdir);
            build.onEnd(() => fs.copySync(from, path.join(target, to), { overwrite: true }));
        },
    };
};

module.exports = [
    graphqlLoaderPlugin(),
    nodeExternalsPlugin(),
    copyPlugin({
        from: "src/type-defs",
        to: "./type-defs",
    }),
];

迁移到SST后,函数栈配置片段如下:

import * as graphqlLoaderPlugin from "@luckycatfactory/esbuild-graphql-loader";

export function API({ stack }: StackContext) {
    const { stackName, stage } = stack;
    console.log(`Deploying ${stackName} to stage: ${stage}`);

    const function = new Function(stack, "function", {
        handler: "./src/lambda.handler",
        runtime: "nodejs20.x",
        memorySize: 768,
        copyFiles: [{ from: "./src/type-defs" }],
        nodejs: {
            esbuild: {
                plugins: [graphqlLoaderPlugin.default()],
            },
        },
        environment: {
           /* ...*/
        },
    });

    const api = new ApiGatewayV1Api(stack, "api", {
        routes: {
            "ANY /graphql": {
                function: function,
                cdk: {
                    method: {
                        apiKeyRequired: true,
                    },
                },
            },
        },
    });

    /* 省略usageplans、apikeys等配置 */
}

触发错误:

TypeError: graphqlLoaderPlugin.default is not a function

即使改为import graphqlLoaderPlugin from "@luckycatfactory/esbuild-graphql-loader";并调用graphqlLoaderPlugin(),错误依然存在。

解决方案

1. 正确导入graphqlLoaderPlugin

该插件的ES模块导出存在兼容问题,直接使用require语法导入即可解决:

const graphqlLoaderPlugin = require("@luckycatfactory/esbuild-graphql-loader").default;

2. 完整迁移所有esbuild插件

将原插件文件中的逻辑整合到SST的TypeScript代码中,完整配置如下:

import { StackContext, Function, ApiGatewayV1Api } from "sst/constructs";
const { nodeExternalsPlugin } = require("esbuild-node-externals");
const graphqlLoaderPlugin = require("@luckycatfactory/esbuild-graphql-loader").default;
const fs = require("fs-extra");
const path = require("path");

// 定义copy插件
const copyPlugin = ({ from, to }) => {
    return {
        name: "copy",
        setup(build) {
            const target = build.initialOptions.outfile
                ? path.dirname(build.initialOptions.outfile)
                : path.resolve(build.initialOptions.outdir);
            build.onEnd(() => fs.copySync(from, path.join(target, to), { overwrite: true }));
        },
    };
};

export function API({ stack }: StackContext) {
    const { stackName, stage } = stack;
    console.log(`Deploying ${stackName} to stage: ${stage}`);

    // 避免使用保留字function作为变量名
    const lambdaFunction = new Function(stack, "function", {
        handler: "./src/lambda.handler",
        runtime: "nodejs20.x",
        memorySize: 768,
        nodejs: {
            esbuild: {
                bundle: true,
                minify: false,
                sourcemap: true,
                target: "es2022",
                plugins: [
                    graphqlLoaderPlugin(),
                    nodeExternalsPlugin(),
                    copyPlugin({
                        from: "src/type-defs",
                        to: "./type-defs",
                    })
                ],
            },
        },
        environment: {
           /* ...*/
        },
    });

    const api = new ApiGatewayV1Api(stack, "api", {
        routes: {
            "ANY /graphql": {
                function: lambdaFunction,
                cdk: {
                    method: {
                        apiKeyRequired: true,
                    },
                },
            },
        },
    });

    /* 省略usageplans、apikeys等配置 */
}

3. 关键注意事项

  • 不要使用JavaScript保留字function作为变量名,替换为lambdaFunction这类合法名称
  • 若仅需简单复制文件,可使用SST自带的copyFiles配置;如果需要自定义复制路径或逻辑,保留自定义copyPlugin更合适
  • 确保所有依赖包(@luckycatfactory/esbuild-graphql-loader、esbuild-node-externals、fs-extra)已正确安装

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 09:39:51