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

Export more Vite types, document presets #8654

Merged
merged 4 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
markdalgleish marked this conversation as resolved.
Show resolved Hide resolved
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
Loading