manawiki / repay

Remix + PayloadCMS
MIT License
83 stars 8 forks source link

Build error with resource routes #23

Open kwabe007 opened 3 months ago

kwabe007 commented 3 months ago

Hi, it seems the build process breaks when a project contains a resource route (A route that does not export a component).

To reproduce:

  1. Create a fresh RePay project.
  2. Add a resource route that does not export a component:
    
    // myroute.tsx

import { redirect } from "@remix-run/node";

export function loader() { return redirect('/'); }


When you now try to run `yarn build`, you get:
```bash
server.ts:71:7 - error TS2769: No overload matches this call.
  Overload 1 of 2, '({ build, getLoadContext, mode, }: { build: ServerBuild | (() => Promise<ServerBuild>); getLoadContext?: GetLoadContextFunction | undefined; mode?: string | undefined; }): RequestHandler', gave the following error.
    Type '(() => Promise<ServerBuild>) | { default: typeof import("/home/kwabe007/test/repay/build/server/index"); assets: { entry: { module: string; imports: string[]; css: never[]; }; routes: { ...; }; url: string; version: string; }; ... 7 more ...; routes: { ...; }; }' is not assignable to type 'ServerBuild | (() => Promise<ServerBuild>)'.
      Type '{ default: typeof import("/home/kwabe007/test/repay/build/server/index"); assets: { entry: { module: string; imports: string[]; css: never[]; }; routes: { root: { id: string; parentId: undefined; path: string; ... 9 more ...; css: string[]; }; "routes/myroute": { ...; }; "routes/_index": { ...; }; }; url: string; ver...' is not assignable to type 'ServerBuild | (() => Promise<ServerBuild>)'.
        Type '{ default: typeof import("/home/kwabe007/test/repay/build/server/index"); assets: { entry: { module: string; imports: string[]; css: never[]; }; routes: { root: { id: string; parentId: undefined; path: string; ... 9 more ...; css: string[]; }; "routes/myroute": { ...; }; "routes/_index": { ...; }; }; url: string; ver...' is not assignable to type 'ServerBuild'.
          Types of property 'routes' are incompatible.
            Type '{ root: { id: string; parentId: undefined; path: string; index: undefined; caseSensitive: undefined; module: Readonly<{ __proto__: null; default: () => any; meta: () => ({ title: string; charSet?: undefined; name?: undefined; content?: undefined; } | { ...; } | { ...; })[]; }>; }; "routes/myroute": { ...; }; "routes...' is not assignable to type 'ServerRouteManifest'.
              Property '"routes/myroute"' is incompatible with index signature.
                Type '{ id: string; parentId: string; path: string; index: undefined; caseSensitive: undefined; module: Readonly<{ __proto__: null; loader: () => TypedResponse<never>; }>; }' is not assignable to type 'Omit<ServerRoute, "children">'.
                  Types of property 'module' are incompatible.
                    Property 'default' is missing in type 'Readonly<{ __proto__: null; loader: () => TypedResponse<never>; }>' but required in type 'ServerRouteModule'.

71       build: vite
         ~~~~~

  node_modules/@remix-run/server-runtime/dist/routeModules.d.ts:199:5
    199     default: any;
            ~~~~~~~
    'default' is declared here.
  env.d.ts:43:5
    43     build: ServerBuild | (() => Promise<ServerBuild>);
           ~~~~~
    The expected type comes from property 'build' which is declared here on type '{ build: ServerBuild | (() => Promise<ServerBuild>); getLoadContext?: GetLoadContextFunction | undefined; mode?: string | undefined; }'

Found 1 error in server.ts:71

error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ERROR: "build:server" exited with 2.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

If you do however add an empty export:

export default function MyRoute() {
    return <></>;
}

The build process works fine. Resource routes are valid routes in Remix so RePay should support it as well. For now I'll just remember to add an empty component export to my routes but hope to see this fixed :)

xHomu commented 3 months ago

Looking into this. Can you share a bit more about your dev environment (OS, node, yarn ver), so I can try to replicate this?

Just in case, I bumped the main package versions on the template, update package.json and see if that make any difference: https://github.com/manawiki/repay/commit/0905869ee19c6064cf74c448837e8b35a515d30d

kwabe007 commented 3 months ago

It still does not work after updating the package versions.

Environment: Ubuntu 22.04.4 LTS (jammy) Node v20.11.1 yarn v1.22.21

Got the same problem while trying to build a docker image from the project. In the docker image I use pnpm instead of yarn.

Docker Environment: node:20.11.1-alpine pnpm v8.15.4

xHomu commented 3 months ago

Looks like this is a type issue with Remix. We can skip it for now by adding // @ts-expect-error in server.ts:

createRequestHandler({
      // @ts-expect-error
      build: vite
        ? () => vite.ssrLoadModule("virtual:remix/server-build")
        : await import("./build/server/index.js"),
      getLoadContext(req, res) {

https://github.com/manawiki/repay/commit/08b5e4f7f5072a679d75077795a7235ac7f7c3fe

I'll dig a bit further in this, we might need a PR into Remix core to completely resolve this.

kwabe007 commented 3 months ago

Now that you mention it, I don't think I've checked if the bug exists on the Remix Vite template. I can check it a bit later.

kwabe007 commented 3 months ago

Looking at the Remix Vite template I see that the code for handling SSR requests is different:

// handle SSR requests
app.all("*", remixHandler);

And it works fine building with a resource route.