Type error when importing server build from `server.ts`
Reproduction
https://stackblitz.com/edit/remix-run-remix-2pvj8y?file=server.ts
System Info
System:
OS: macOS 14.2
CPU: (8) arm64 Apple M1
Memory: 71.86 MB / 8.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node
Yarn: 1.22.19 - ~/.yarn/bin/yarn
npm: 10.2.3 - ~/.nvm/versions/node/v20.10.0/bin/npm
bun: 1.0.3 - ~/.bun/bin/bun
Browsers:
Chrome: 120.0.6099.129
Safari: 17.2
npmPackages:
@remix-run/dev: ^2.4.0 => 2.4.0
@remix-run/eslint-config: ^2.4.0 => 2.4.0
@remix-run/express: ^2.4.0 => 2.4.0
@remix-run/node: ^2.4.0 => 2.4.0
@remix-run/react: ^2.4.0 => 2.4.0
vite: ^5.0.10 => 5.0.10
Used Package Manager
npm
Expected Behavior
Clean TS slate
Actual Behavior
When I add to custom TS server setup:
app.all(
"*",
createRequestHandler({
build: vite
? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId)
: await import("./build/server/index.js"),
}),
);
I get: Type '(() => Promise<Record<string, any>>) | typeof import("/Users/mattiarasulo/Desktop/web-development-desktop.nosync/call-center-directory/build/server/index")' is not assignable to type 'ServerBuild | (() => Promise<ServerBuild>)'.
Type '() => Promise<Record<string, any>>' is not assignable to type 'ServerBuild | (() => Promise<ServerBuild>)'.
Type '() => Promise<Record<string, any>>' is not assignable to type '() => Promise<ServerBuild>'.
Type 'Promise<Record<string, any>>' is not assignable to type 'Promise<ServerBuild>'.
Type 'Record<string, any>' is missing the following properties from type 'ServerBuild': mode, entry, routes, assets, and 3 more.ts(2322)
server.d.ts(18, 5): The expected type comes from property 'build' which is declared here on type '{ build: ServerBuild | (() => Promise<ServerBuild>); getLoadContext?: GetLoadContextFunction | undefined; mode?: string | undefined; }'
Hey @pcattori I think this has been introduced in the latest 2.4.0 release of @remix-run/dev, I'll just add a @ts-expect-error for now. Thanks for your help!
I'm not sure there's an alternative here. In a fresh project when running the dev server before running the build, "./build/server/index.js" doesn't even exist yet, so even if Vite was configured to output types, it would still be a type error. To me it makes sense to use @ts-expect-error as you said. Given this is pretty much a one-time setup, I don't think the types are as critical here.
Doesn't look great, but it works:
app.all('*', async (request, reply) => {
try {
const handler = createRequestHandler({
// https://github.com/remix-run/remix/issues/8343#issuecomment-1867179525
// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
// @ts-ignore - expected type mismatch
build: vite
? () => vite.ssrLoadModule('virtual:remix/server-build')
: // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
// @ts-ignore - expected non-existent file (pre-build)
await import('../../build/server'),
});
return handler(request, reply);
} catch (error) {
captureException('could not render request', error, {
url: request.url,
});
return reply.status(500).send(error);
}
});
Yeah, is there any specific reason for not using @ts-expect-error directly instead of needing two comments?
Yeah, is there any specific reason for not using @ts-expect-error directly instead of needing two comments?
Because await import('../../build/server') is not going to trigger an error if there is a build. However, in CI, linting happens before build, causing there always to be an error.
I think the first use of @ts-ignore could be changed to @ts-expect-error though
Changed the title and removed the Vite tag since this has always been the case with Remix server builds, even with the classic compiler. Definitely something I'm keen to improve, but just not directly related to Vite.
Thank you for checking this out @pcattori you are the man, I really appreciate you! If there's anything I can do to contribute, I'd be keen to!
Hey, I have the same issue. My use-case is to lint with eslint and typecheck with tsc before building all assets for the Cloudflare.
Is there any timeline for that?
Thank you for opening this issue, and our apologies we haven't gotten around to it yet!
With the release of React Router v7 we are sun-setting continued development/maintenance on Remix v2. If you have not already upgraded to React Router v7, we recommend you do so. We've tried to make the upgrade process as smooth as possible with our Future Flags. We are now in the process of cleaning up outdated issues and pull requests to improve the overall hygiene of our repositories.
We plan to continue to address 2 types of issues in Remix v2:
- Bugs that pose security concerns
- Bugs that prevent upgrading to React Router v7
If you believe this issue meets one of those criteria, please respond or create a new issue.
For all other issues, ongoing maintenance will be happening in React Router v7, so:
- If this is a bug, please reopen this issue in that repo with a new minimal reproduction against v7
- If this is a feature request, please open a new Proposal Discussion in React Router, and if it gets enough community support it can be considered for implementation
If you have any questions you can always reach out on Discord. Thanks again for providing feedback and helping us make our framework even better!