Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I can't prerender when using cloudflare or cloudflare-d1 templates #31

Open
gmtborges opened this issue Dec 10, 2024 · 6 comments
Open

Comments

@gmtborges
Copy link

As mentioned here to include NODE_ENV=production in the build script remix-run/react-router#12508 (comment) it fixed in the default template, but using cloudflare or d1 it still fails.

The error

x Build failed in 307ms
[react-router] Cannot convert undefined or null to object
    at Function.values (<anonymous>)
    at groupRoutesByParentId2 (/Users/gustavo/repos/estudos/js/cf-rr/node_modules/.pnpm/@[email protected]_@[email protected][email protected][email protected]_react@1_3qikndsdtuyn7j5gt5pgxdglyi/node_modules/@react-router/dev/dist/vite.js:2650:10)
    at createPrerenderRoutes (/Users/gustavo/repos/estudos/js/cf-rr/node_modules/.pnpm/@[email protected]_@[email protected][email protected][email protected]_react@1_3qikndsdtuyn7j5gt5pgxdglyi/node_modules/@react-router/dev/dist/vite.js:2661:76)
    at handlePrerender (/Users/gustavo/repos/estudos/js/cf-rr/node_modules/.pnpm/@[email protected]_@[email protected][email protected][email protected]_react@1_3qikndsdtuyn7j5gt5pgxdglyi/node_modules/@react-router/dev/dist/vite.js:2477:16)
    at Object.handler (/Users/gustavo/repos/estudos/js/cf-rr/node_modules/.pnpm/@[email protected]_@[email protected][email protected][email protected]_react@1_3qikndsdtuyn7j5gt5pgxdglyi/node_modules/@react-router/dev/dist/vite.js:2029:13)
    at async Promise.all (index 0)
    at PluginDriver.hookParallel (file:///Users/gustavo/repos/estudos/js/cf-rr/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:20740:9)
    at file:///Users/gustavo/repos/estudos/js/cf-rr/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:21783:13
    at catchUnfinishedHookActions (file:///Users/gustavo/repos/estudos/js/cf-rr/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:21158:16)
    at Module.build (file:///Users/gustavo/repos/estudos/js/cf-rr/node_modules/.pnpm/[email protected]_@[email protected]/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:65449:16) {
  code: 'PLUGIN_ERROR',
  plugin: 'react-router',
  hook: 'writeBundle'
}
 ELIFECYCLE  Command failed with exit code 1.
@sondrehav
Copy link

sondrehav commented Dec 11, 2024

Getting the same in the node-custom-server-template.

x Build failed in 283ms
[react-router] Cannot convert undefined or null to object
    at Function.values (<anonymous>)
    at groupRoutesByParentId2 (/home/sondre/Documents/Progging/testfaceklmrekljkljklse/node_modules/@react-router/dev/dist/vite.js:2650:10)
    at createPrerenderRoutes (/home/sondre/Documents/Progging/testfaceklmrekljkljklse/node_modules/@react-router/dev/dist/vite.js:2661:76)

node v22.12.0, react-router 7.0.2, vite 5.4.11, react 19.0.0

It happens with this react-router.config.ts:

import type { Config } from "@react-router/dev/config";

export default {
  ssr: true,
  async prerender() {
    return ['/'];
  },
} satisfies Config;

@alrightsure
Copy link

I am getting the same with the vercel template.

@HatemJerbi
Copy link

Getting the same in the node-custom-server-template.

x Build failed in 283ms
[react-router] Cannot convert undefined or null to object
    at Function.values (<anonymous>)
    at groupRoutesByParentId2 (/home/sondre/Documents/Progging/testfaceklmrekljkljklse/node_modules/@react-router/dev/dist/vite.js:2650:10)
    at createPrerenderRoutes (/home/sondre/Documents/Progging/testfaceklmrekljkljklse/node_modules/@react-router/dev/dist/vite.js:2661:76)

node v22.12.0, react-router 7.0.2, vite 5.4.11, react 19.0.0

It happens with this react-router.config.ts:

import type { Config } from "@react-router/dev/config";

export default {
  ssr: true,
  async prerender() {
    return ['/'];
  },
} satisfies Config;

same problem with :
node v22.12.0, react-router 7.1.1, vite 6.0.6, react 19.0.0

@HatemJerbi
Copy link

HatemJerbi commented Dec 28, 2024

Here's how I resolved this issue:

my vite.config.ts :

import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig(({ isSsrBuild }) => ({
  plugins: [
    reactRouter(),
    {
      name: "react-router-custom-express-server",
      config: () => ({
        build: {
          rollupOptions: isSsrBuild
            ? {
                input: { "assets/server-build.js": "virtual:react-router/server-build", "index.js": "./server/app.ts" },
                output: {
                  entryFileNames: "[name]",
                },
              }
            : undefined,
        },
      }),
    },
    tsconfigPaths(),
  ],
}));

react-router.config.ts :

import type { Config } from "@react-router/dev/config";

export default {
  // Config options...
  // Server-side render by default, to enable SPA mode set this to `false`
  ssr: true,
  serverBuildFile: "assets/server-build.js", // 🚨 Dont forget this
  async prerender() {
    return ['/'];
  },
} satisfies Config;

@kennygoff
Copy link

This is also effecting Netlify. Creating a project the latest template and adding prerender:['/'] with ssr:true causes a build error.

export default {
  // Config options...
  // Server-side render by default, to enable SPA mode set this to `false`
  ssr: true,
  prerender: ["/"],
} satisfies Config;

Error:

x Build failed in 62ms
[react-router] Cannot convert undefined or null to object
    at Function.values (<anonymous>)
    at groupRoutesByParentId2 (/Users/kennygoff/dev/web/my-react-router-app/node_modules/@react-router/dev/dist/vite.js:2706:10)
    at createPrerenderRoutes (/Users/kennygoff/dev/web/my-react-router-app/node_modules/@react-router/dev/dist/vite.js:2717:76)
    at handlePrerender (/Users/kennygoff/dev/web/my-react-router-app/node_modules/@react-router/dev/dist/vite.js:2533:16)
    at Object.handler (/Users/kennygoff/dev/web/my-react-router-app/node_modules/@react-router/dev/dist/vite.js:2040:13)
    at async Promise.all (index 0)
    at PluginDriver.hookParallel (file:///Users/kennygoff/dev/web/my-react-router-app/node_modules/rollup/dist/es/shared/node-entry.js:20802:9)
    at file:///Users/kennygoff/dev/web/my-react-router-app/node_modules/rollup/dist/es/shared/node-entry.js:21845:13
    at catchUnfinishedHookActions (file:///Users/kennygoff/dev/web/my-react-router-app/node_modules/rollup/dist/es/shared/node-entry.js:21220:16)
    at Module.build (file:///Users/kennygoff/dev/web/my-react-router-app/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:65449:16) {
  code: 'PLUGIN_ERROR',
  plugin: 'react-router',
  hook: 'writeBundle'
}

@kennygoff
Copy link

kennygoff commented Jan 4, 2025

@HatemJerbi's solution wasn't working for me it seemed to just generate two server files, the react-router one and the custom one but wasn't wired up to correctly prerender.

Did a little digging on this and I think the source of the problem is that getPrerenderBuildAndHandler (see here build.routes is undefined) in the vite plugin is expecting the server build file to contain the exports from the default server export. The custom servers defined in the template projects don't export those out of assets/index.js.

// build/server/assets/server-build-HASH.js

// This build output is what the plugin expects for prerender
export {
  serverManifest as assets,
  assetsBuildDirectory,
  basename,
  entry,
  future,
  isSpaMode,
  publicPath,
  // Importantly, this routes object
  routes,
};
// build/server/index.js

// This is what the prerender is actually looking at, the custom server's config
export {
  config,
  app as default
};

I'm not sure if the correct solution is to re-export import("virtual:react-router/server-build") form the "custom" server output or if there needs to be a way to specify a build/config file for the server that isn't index.js. serverBuildFile in react-router.config.ts seems to also change the name of the file generated so I don't think that's exactly what should be used here (docs).

Hacking in my server build filename into the prebuilt vite plugin in node_modules "works" so I think it might be the latter.

// node_modules/@react-router/dev/dist/vite.js
async function getPrerenderBuildAndHandler(viteConfig, reactRouterConfig, serverBuildDirectory) {
  let serverBuildPath = path4.join(
    serverBuildDirectory,
    "assets/server-build-BKijuY2G.js" // Hacky replacement just to test
  );
  console.log('serverBuildPath', url.pathToFileURL(serverBuildPath).toString())
  let build = await import(url.pathToFileURL(serverBuildPath).toString());
  let { createRequestHandler: createHandler } = await import("react-router");
  return {
    build,
    handler: createHandler(build, viteConfig.mode)
  };
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants