remix: Setting server in remix.config.js fails when using express adapter
What version of Remix are you using?
1.4.3
Steps to Reproduce
- Create app using
create-remix(express, just the basics, typescript) - Set
serverinremix.config.jsto let remix produce one consolidated build. npm run buildworksnpm run devfails
Sample code here: https://github.com/edwin177/remix-express/tree/express-server-build
Expected Behavior
Server should load
Actual Behavior
App crashes with the following error:
/home/xxx/remix-express/node_modules/@remix-run/server-runtime/routes.js:18
return Object.entries(manifest).filter(([, route]) => route.parentId === parentId).map(([id, route]) => ({ ...route,
^
TypeError: Cannot convert undefined or null to object
at Function.entries (<anonymous>)
at Object.createRoutes (/home/xxx/remix-express/node_modules/@remix-run/server-runtime/routes.js:18:17)
at Object.createRequestHandler (/home/xxx/remix-express/node_modules/@remix-run/server-runtime/server.js:26:25)
at createRequestHandler (/home/xxx/remix-express/node_modules/@remix-run/express/server.js:35:28)
at Object.<anonymous> (/home/xxx/remix-express/build/index.js:42:5)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:12)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:75:12)
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 15
- Comments: 16 (2 by maintainers)
I ran into this with Remix 1.8.2. It seems like the problem is twofold.
Problem 1: overridden entrypoint to esbuild
Setting
serverinremix.config.jschanges the esbuild config. I think the problem may be here? https://github.com/remix-run/remix/blob/8fb82b27bcf7174fcd83dd0fc63d99764ff264c1/packages/remix-dev/compiler/compilerServer.ts#L35-L43As a result,
build/index.jsonly includes things imported from theserverfile. As an extreme example, when theserverfile only includesthen
build/index.jsonly includes that:Problem 2: cyclic dependencies
If the server is bundled into the same file as the application, this creates a cyclic dependency.
node build/index.jsto start the servernoderequiresbuild/index.jscreateRequestHandlercall, and attempts to requirebuild/index.jsrequirereturns{}to avoid an infinite loopcreateRoutesthrows becausemanifestisundefinedA workaround that doesn’t require creating a separate esbuild step
I worked around these issues by removing
serverfromremix.config.jsand putting the following code inapp/entry.server.tsxThe
runfunction creates the express app and callslisten. Because it runs in the next tick, requiringbuild/index.jsdoes not create a loop.Solving the problems
I think if
serveris specified in the config, the compiler needs to produce two files.build/index.jswould be produced from theserverfile andbuild/app.jswould be the application code.Hey folks, for whoever is running into this issue like I did this past week (Remix 1.18.1), I’ve managed to circumvent this problem with a mix of the suggestion from @mfadlyramadhan above and some custom setup I did for running the Express server during local development, including support for hot-module replacement.
i’ve created a repo here that you can take a look or even use it in case you want to have Remix + Express (TS) + development with HMR + Docker builds.
https://github.com/brunojppb/remix-express-typescript
The secret is mostly in the
remix.config.jsto only add theserverentry during production builds as you can see here which avoids this bug.Then I customised the Express server to have a dynamic entrypoint where the development and production setup can be adjusted based on your needs.
Ideally, would be great if the Remix team could make the
serverentry work smoothly with the entire Express Adapter + TypeScript compilation setup.Last, but not least, thanks to the Remix team for the incredible work put on this framework! 👏
CC: @raulfdm @leoweigand @dge808
This issue is still happening. (try upgrading from 1.2.3 to 1.7.4 Today)
Btw, still getting the same error with 1.7.0.
Sample code: https://github.com/edwin177/remix-express-1.7
I’m relatively new to remix so please correct me if I wrong. I’ve somehow managed to run the remix with express adapter, setting the
serverinremix.config.jstoserver.ts. Then in theserver.tsI just use theimport * as build from "@remix-run/dev/server-build". Here is what I did:I don’t know if this is the correct way to do it. I have also looked on the other adapter templates and it shows the usage of the
import * as build from "@remix-run/dev/server-build".I’m sorry if my english is bad cause it’s not even my second language. Hopefully this helps as a workaround until we have the correct way to do it.
Hmm from the docs
I thought I could just throw in a server.ts but running
node ./build/index.js&remix watcherrorsWould be amazing if a custom Express (Fastify, Koa) typescript server wouldn’t require a custom pipeline but could “just” work like that and the docs actually sound like it should work, at least I understand them like that
Btw, I just tried this with v1.5.0, and I’m getting the same error as I did with v1.4.3.