sst / ion

SST v3
https://sst.dev
MIT License
1.57k stars 200 forks source link

Using remix with a custom server fails to find handler after linking #981

Open barakcodes opened 1 week ago

barakcodes commented 1 week ago

I'm using remix with hono as the server (basically it's a Hono app with remix middleware) during dev when I link anything to remix I get the error

Could not find handler file "path/to/lambda.handler" for function "RemixComponentName"

with this config

 new sst.aws.Remix("MyWeb", {
      environment: {
        NODE_ENV: $dev ? "development" : "production",
      },
      link: [...Object.values(infra.secrets), infra.bus],
      transform: {
        server: {
          handler: "lambda.handler",
          nodejs: {
            esbuild: {
              external: ["virtual:remix/server-build"],
              loader: {
                ".node": "file",
              },
            },
          },
        },
      },
    });

and the dev mode fails with

failed to load config from /path/to/project/vite.config.ts
error when starting dev server:
Error: The service was stopped: write EPIPE
    at /path/to/project/node_modules/vite/node_modules/esbuild/lib/main.js:968:34

which I think sst is trying to use esbuild for dev as well.

The weird part of all this is I can get it around this running it the older way on dev "sst shell vite" (like a savage) and when deployed everything works, and when run without link, it works fine in dev as well

 new sst.aws.Remix('MyWeb', {
      environment: {
         NODE_ENV: $dev ? "development" : "production",
      },
      transform: {
        server: {
          handler: 'functions/server.handler',
          nodejs: {
            esbuild: {
               external:['virtual:remix/server-build'],
               loader: {
                '.node': 'file',
              },
            },
          },
        },
      },
    })

you can use this repo to reproduce the issue. Am I missing something??

barakcodes commented 1 week ago

So I think I figure out what is causing the issue, so for dev it seems like sst is using the "empty function" from sst/platform/functions/empty-function so when a custom function is passed without the bundle it would still reference the same directory but different paths. for my case the fix was to rename the server file to index.handler or just in the ssr component override the handler in args. I'm not so sure how this would work for other scenarios that don't use vite for dev.

transform(
      { ...args.transform?.server, handler: "index.handler" } as any,
      `${name}DevServer`,
      {
        description: `${name} dev server`,
        runtime: "nodejs20.x",
        timeout: "20 seconds",
        memory: "128 MB",
        bundle: path.join($cli.paths.platform, "functions", "empty-function"),
        handler: "index.handler",
        environment: args.environment,
        permissions: args.permissions,
        link: args.link,
        live: false,
      },
      { parent },
    )

easier fix(rename)

      environment: {
        NODE_ENV: $dev ? "development" : "production",
      },
      link: [infra.bus, ...Object.values(infra.secrets)],
      transform: {
        server: {
          handler: "index.handler",
          nodejs: {
            esbuild: {
              external: ["virtual:remix/server-build"],
              loader: {
                ".node": "file",
              },
            },
          },
        },
      },