Skip to content

Commit

Permalink
Export more Vite types, document presets (#8654)
Browse files Browse the repository at this point in the history
Co-authored-by: Pedro Cattori <pcattori@gmail.com>
  • Loading branch information
markdalgleish and pcattori committed Feb 1, 2024
1 parent 920b7d2 commit f0688dd
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/cool-fishes-attack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/dev": patch
---

Vite: Provide `Unstable_ServerBundlesFunction` and `Unstable_VitePluginConfig` types
120 changes: 120 additions & 0 deletions docs/future/presets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
title: Presets (Unstable)
---

# Presets (Unstable)

The [Remix Vite plugin][remix-vite] supports a `presets` option to ease integration with other tools and hosting providers.

Presets can only do two things:

- Configure the Remix Vite plugin on your behalf.
- Validate the resolved config.

The config returned by each preset is merged in the order they were defined. Any config directly passed to the Remix Vite plugin will be merged last. This means that user config will always take precedence over any presets.

## Using a preset

Presets are designed to be published to npm and used within your Vite config. For example, Remix ships with a preset for Cloudflare:

```ts filename=vite.config.ts lines=[3,10]
import {
unstable_vitePlugin as remix,
unstable_cloudflarePreset as cloudflare,
} from "@remix-run/dev";
import { defineConfig } from "vite";

export default defineConfig({
plugins: [
remix({
presets: [cloudflare()],
}),
],
// etc.
});
```

## Creating a preset

Presets conform to the following `Unstable_Preset` type:

```ts
type Unstable_Preset = {
name: string;

remixConfig?: () =>
| RemixConfigPreset
| Promise<RemixConfigPreset>;

remixConfigResolved?: (args: {
remixConfig: ResolvedVitePluginConfig;
}) => void | Promise<void>;
};
```

### Defining preset config

As a basic example, let's create a preset that configures a [server bundles function][server-bundles]:

```ts filename=my-cool-preset.ts
import type { Unstable_Preset as Preset } from "@remix-run/dev";

export function myCoolPreset(): Preset {
return {
name: "my-cool-preset",
remixConfig: () => ({
serverBundles: ({ branch }) => {
const isAuthenticatedRoute = branch.some((route) =>
route.id.split("/").includes("_authenticated")
);

return isAuthenticatedRoute
? "authenticated"
: "unauthenticated";
},
}),
};
}
```

### Validating config

It's important to remember that other presets and user config can still override the values returned from your preset.

In our example preset, the `serverBundles` function could be overridden with a different, conflicting implementation. If we want to validate that the final resolved config contains the `serverBundles` function from our preset, we can do this with the `remixConfigResolved` hook:

```ts filename=my-cool-preset.ts lines=[22-26]
import type {
Unstable_Preset as Preset,
Unstable_ServerBundlesFunction as ServerBundlesFunction,
} from "@remix-run/dev";

const serverBundles: ServerBundlesFunction = ({
branch,
}) => {
const isAuthenticatedRoute = branch.some((route) =>
route.id.split("/").includes("_authenticated")
);

return isAuthenticatedRoute
? "authenticated"
: "unauthenticated";
};

export function myCoolPreset(): Preset {
return {
name: "my-cool-preset",
remixConfig: () => ({ serverBundles }),
remixConfigResolved: ({ remixConfig }) => {
if (remixConfig.serverBundles !== serverBundles) {
throw new Error("`serverBundles` was overridden!");
}
},
};
}
```

The `remixConfigResolved` hook should only be used in cases where it would be an error to merge or override your preset's config.

[remix-vite]: ./vite
[server-bundles]: ./server-bundles
4 changes: 2 additions & 2 deletions docs/future/server-bundles.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export default defineConfig({
plugins: [
remix({
serverBundles: ({ branch }) => {
const isAuthenticatedRoute = branch.some(
(route) => route.id === "routes/_authenticated"
const isAuthenticatedRoute = branch.some((route) =>
route.id.split("/").includes("_authenticated")
);

return isAuthenticatedRoute
Expand Down
4 changes: 3 additions & 1 deletion docs/future/vite.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ to `false`.

#### presets

An array of Remix config presets to ease integration with different platforms and tools.
An array of [presets] to ease integration with
other tools and hosting providers.

#### serverBuildFile

Expand Down Expand Up @@ -1249,3 +1250,4 @@ We're definitely late to the Vite party, but we're excited to be here now!
[cloudflare-proxy-ctx]: https://github.com/cloudflare/workers-sdk/issues/4876
[cloudflare-proxy-caches]: https://github.com/cloudflare/workers-sdk/issues/4879
[how-fix-cjs-esm]: https://www.youtube.com/watch?v=jmNuEEtwkD4
[presets]: ./presets
7 changes: 6 additions & 1 deletion packages/remix-dev/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@ export * as cli from "./cli/index";

export type { Manifest as AssetsManifest } from "./manifest";
export { getDependenciesToBundle } from "./dependencies";
export type { Unstable_BuildManifest, Unstable_Preset } from "./vite";
export type {
Unstable_BuildManifest,
Unstable_Preset,
Unstable_ServerBundlesFunction,
Unstable_VitePluginConfig,
} from "./vite";
export { unstable_vitePlugin, unstable_cloudflarePreset } from "./vite";
2 changes: 2 additions & 0 deletions packages/remix-dev/vite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import type { RemixVitePlugin } from "./plugin";
export type {
BuildManifest as Unstable_BuildManifest,
Preset as Unstable_Preset,
VitePluginConfig as Unstable_VitePluginConfig,
ServerBundlesFunction as Unstable_ServerBundlesFunction,
} from "./plugin";

export const unstable_vitePlugin: RemixVitePlugin = (...args) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-dev/vite/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const configRouteToBranchRoute = (
configRoute: ConfigRoute
): BranchRoute => pick(configRoute, branchRouteProperties);

type ServerBundlesFunction = (args: {
export type ServerBundlesFunction = (args: {
branch: BranchRoute[];
}) => string | Promise<string>;

Expand Down

0 comments on commit f0688dd

Please sign in to comment.