Skip to content

Commit

Permalink
Vite: Pass remixUserConfig to preset config hook (#8797)
Browse files Browse the repository at this point in the history
  • Loading branch information
markdalgleish authored Feb 20, 2024
1 parent d16dce8 commit 85d988f
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .changeset/mighty-carpets-lie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/dev": patch
---

Vite: Pass `remixUserConfig` to preset `remixConfig` hook
6 changes: 3 additions & 3 deletions docs/future/presets.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ Presets conform to the following `Preset` type:
type Preset = {
name: string;

remixConfig?: () =>
| RemixConfigPreset
| Promise<RemixConfigPreset>;
remixConfig?: (args: {
remixUserConfig: VitePluginConfig;
}) => RemixConfigPreset | Promise<RemixConfigPreset>;

remixConfigResolved?: (args: {
remixConfig: ResolvedVitePluginConfig;
Expand Down
63 changes: 55 additions & 8 deletions integration/vite-presets-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,46 @@ import dedent from "dedent";

import { viteBuild, test, createProject } from "./helpers/vite.js";

const js = String.raw;

const files = {
"vite.config.ts": dedent`
"vite.config.ts": dedent(js`
import { vitePlugin as remix } from "@remix-run/dev";
import fs from "node:fs/promises";
import serializeJs from "serialize-javascript";
let isDeepFrozen = (obj: any) =>
Object.isFrozen(obj) &&
Object.keys(obj).every(
prop => typeof obj[prop] !== 'object' || isDeepFrozen(obj[prop])
);
export default {
plugins: [remix({
presets: [
// Ensure user config is passed to remixConfig hook
{
name: "test-preset",
remixConfig: async ({ remixUserConfig: { presets, ...restUserConfig } }) => {
if (!Array.isArray(presets)) {
throw new Error("Remix user config doesn't have presets array.");
}
let expected = JSON.stringify({ appDirectory: "app"});
let actual = JSON.stringify(restUserConfig);
if (actual !== expected) {
throw new Error([
"Remix user config wasn't passed to remixConfig hook.",
"Expected: " + expected,
"Actual: " + actual,
].join(" "));
}
return {};
},
},
// Ensure preset config takes lower precedence than user config
{
name: "test-preset",
Expand Down Expand Up @@ -46,16 +77,20 @@ const files = {
}),
},
// Ensure remixConfig is called with a frozen Remix user config
{
name: "test-preset",
remixConfig: async ({ remixUserConfig }) => {
await fs.writeFile("PRESET_REMIX_CONFIG_META.json", JSON.stringify({
remixUserConfigFrozen: isDeepFrozen(remixUserConfig),
}), "utf-8");
}
},
// Ensure remixConfigResolved is called with a frozen Remix config
{
name: "test-preset",
remixConfigResolved: async ({ remixConfig }) => {
let isDeepFrozen = (obj: any) =>
Object.isFrozen(obj) &&
Object.keys(obj).every(
prop => typeof obj[prop] !== 'object' || isDeepFrozen(obj[prop])
);
await fs.writeFile("PRESET_REMIX_CONFIG_RESOLVED_META.json", JSON.stringify({
remixConfigFrozen: isDeepFrozen(remixConfig),
}), "utf-8");
Expand Down Expand Up @@ -90,7 +125,7 @@ const files = {
appDirectory: "app",
})],
}
`,
`),
};

test("Vite / presets", async () => {
Expand Down Expand Up @@ -124,6 +159,18 @@ test("Vite / presets", async () => {
// Ensure preset config takes lower precedence than user config
expect(remixConfig.serverModuleFormat).toBe("esm");

// Ensure `remixConfig` is called with a frozen Remix user config
expect(
JSON.parse(
await fs.readFile(
path.join(cwd, "PRESET_REMIX_CONFIG_META.json"),
"utf-8"
)
)
).toEqual({
remixUserConfigFrozen: true,
});

// Ensure `remixConfigResolved` is called with a frozen Remix config
expect(
JSON.parse(
Expand Down
9 changes: 7 additions & 2 deletions packages/remix-dev/vite/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ type RemixConfigPreset = Omit<VitePluginConfig, ExcludedRemixConfigPresetKey>;

export type Preset = {
name: string;
remixConfig?: () => RemixConfigPreset | Promise<RemixConfigPreset>;
remixConfig?: (args: {
remixUserConfig: VitePluginConfig;
}) => RemixConfigPreset | Promise<RemixConfigPreset>;
remixConfigResolved?: (args: {
remixConfig: ResolvedVitePluginConfig;
}) => void | Promise<void>;
Expand Down Expand Up @@ -527,6 +529,9 @@ let deepFreeze = (o: any) => {

export type RemixVitePlugin = (config?: VitePluginConfig) => Vite.Plugin[];
export const remixVitePlugin: RemixVitePlugin = (remixUserConfig = {}) => {
// Prevent mutations to the user config
remixUserConfig = deepFreeze(remixUserConfig);

let viteCommand: Vite.ResolvedConfig["command"];
let viteUserConfig: Vite.UserConfig;
let viteConfigEnv: Vite.ConfigEnv;
Expand Down Expand Up @@ -556,7 +561,7 @@ export const remixVitePlugin: RemixVitePlugin = (remixUserConfig = {}) => {
}

let remixConfigPreset: VitePluginConfig = omit(
await preset.remixConfig(),
await preset.remixConfig({ remixUserConfig }),
excludedRemixConfigPresetKeys
);

Expand Down

0 comments on commit 85d988f

Please sign in to comment.