Skip to content

Commit

Permalink
Update docs regarding SPA Template ssr.noExternal setting (#8957)
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 authored and IgnusG committed Mar 4, 2024
1 parent c60d43c commit 1455009
Showing 1 changed file with 34 additions and 7 deletions.
41 changes: 34 additions & 7 deletions docs/future/spa-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,14 +222,41 @@ startTransition(() => {

- You cannot call `serverLoader`/`serverAction` from your `clientLoader`/`clientAction` methods since there is no running server -- those will throw a runtime error if called

- It's important to note that Remix SPA mode generates your `index.html` file by performing a "pre-render" of your root route on the server during the build
### Server Build

- This means that while you're creating a SPA, you still have a "server build" and "server render" step, so you do need to be careful about using dependencies that reference client-only aspects such as `document`, `window`, `localStorage`, etc.
- Generally speaking, the way to resolve these issues is to import any browser-only libraries from `entry.client.tsx` so they don't end up in the server build
- Otherwise, you can generally solve these by using [`React.lazy`][react-lazy] or the [`<ClientOnly>`][client-only] component from `remix-utils`
It's important to note that Remix SPA mode generates your `index.html` file by performing a "pre-render" of your root route on the server during the build

- The [SPA Mode template][spa-mode-template] enables the Vite [ssr.noExternal][vite-ssr-noexternal] option by default to automatically bundle all of your dependencies during the server build to avoid most ESM/CJS issues
- This may slow down your build a bit — if so, you can try removing this option, or switching to a more targeted array containing the specific dependencies you wish to bundle
- This means that while you're creating a SPA, you still have a "server build" and "server render" step, so you do need to be careful about using dependencies that reference client-only aspects such as `document`, `window`, `localStorage`, etc.
- Generally speaking, the way to resolve these issues is to import any browser-only libraries from `entry.client.tsx` so they don't end up in the server build
- Otherwise, you can generally solve these by using [`React.lazy`][react-lazy] or the [`<ClientOnly>`][client-only] component from `remix-utils`

### CJS/ESM Dependency Issues

If you are running into ESM/CJS issues with your app dependencies you may need to play with the Vite [ssr.noExternal][vite-ssr-noexternal] option to include certain dependencies in your server bundle:

```ts filename=vite.config.ts lines=[12-15]
import { vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
plugins: [
remix({
ssr: false,
}),
tsconfigPaths(),
],
ssr: {
// Bundle `problematic-dependency` into the server build
noExternal: ["problematic-dependency"],
},
// ...
});
```

These issues are usually due to dependencies whose published code is incorrectly-configured for CJS/ESM. By including the specific dependency in `ssr.noExternal`, Vite will bundle the dependency into the server build and can help avoid runtime import issues when running your server.

If you have the opposite use-case and you specifically want to keep dependencies external to the bundle, you can use the opposite [`ssr.external`][vite-ssr-external] option.

## Migrating from React Router

Expand Down Expand Up @@ -273,5 +300,5 @@ Once you've got all your routes living in their own files, you can:
[client-only]: https://github.com/sergiodxa/remix-utils?tab=readme-ov-file#clientonly
[vite-preview]: https://vitejs.dev/guide/cli#vite-preview
[sirv-cli]: https://www.npmjs.com/package/sirv-cli
[spa-mode-template]: https://github.com/remix-run/remix/tree/main/templates/spa
[vite-ssr-noexternal]: https://vitejs.dev/config/ssr-options#ssr-noexternal
[vite-ssr-external]: https://vitejs.dev/config/ssr-options#ssr-external

0 comments on commit 1455009

Please sign in to comment.