Skip to content

Commit

Permalink
Vite: Validate MDX plugin order
Browse files Browse the repository at this point in the history
  • Loading branch information
markdalgleish committed Feb 6, 2024
1 parent 1f68b3d commit 52aea1f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/forty-squids-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/dev": patch
---

Vite: Validate that the MDX Rollup plugin, if present, is placed before Remix in Vite config
33 changes: 33 additions & 0 deletions integration/vite-plugin-order-validation-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { test, expect } from "@playwright/test";
import dedent from "dedent";

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

test.describe(() => {
let cwd: string;
let buildResult: ReturnType<typeof viteBuild>;

test.beforeAll(async () => {
cwd = await createProject({
"vite.config.ts": dedent`
import { unstable_vitePlugin as remix } from "@remix-run/dev";
import mdx from "@mdx-js/rollup";
export default {
plugins: [
remix(),
mdx(),
],
}
`,
});

buildResult = viteBuild({ cwd });
});

test("Vite / plugin order validation / MDX", () => {
expect(buildResult.stderr.toString()).toContain(
'Error: The "@mdx-js/rollup" plugin should be placed before the Remix plugin in your Vite config file'
);
});
});
22 changes: 22 additions & 0 deletions packages/remix-dev/vite/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,11 @@ export const remixVitePlugin: RemixVitePlugin = (remixUserConfig = {}) => {
};
};

let pluginIndex = (pluginName: string) => {
invariant(viteConfig);
return viteConfig.plugins.findIndex((plugin) => plugin.name === pluginName);
};

let getServerEntry = async () => {
invariant(viteConfig, "viteconfig required to generate the server entry");

Expand Down Expand Up @@ -955,6 +960,7 @@ export const remixVitePlugin: RemixVitePlugin = (remixUserConfig = {}) => {
await initEsModuleLexer;

viteConfig = resolvedViteConfig;
invariant(viteConfig);

// We load the same Vite config file again for the child compiler so
// that both parent and child compiler's plugins have independent state.
Expand Down Expand Up @@ -986,6 +992,22 @@ export const remixVitePlugin: RemixVitePlugin = (remixUserConfig = {}) => {
"Vite config file was unable to be resolved for Remix child compiler"
);

// Validate that commonly used Rollup plugins that need to run before
// Remix are in the correct order. This is because Rollup plugins can't
// set `enforce: "pre"` like Vite plugins can. Explicitly validating
// this provides a much nicer developer experience.
let rollupPrePlugins = [
{ pluginName: "@mdx-js/rollup", displayName: "@mdx-js/rollup" },
];
for (let prePlugin of rollupPrePlugins) {
let prePluginIndex = pluginIndex(prePlugin.pluginName);
if (prePluginIndex >= 0 && prePluginIndex > pluginIndex("remix")) {
throw new Error(
`The "${prePlugin.displayName}" plugin should be placed before the Remix plugin in your Vite config file`
);
}
}

viteChildCompiler = await vite.createServer({
...viteUserConfig,
mode: viteConfig.mode,
Expand Down

0 comments on commit 52aea1f

Please sign in to comment.