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

fix(remix-dev/vite): add Vite commands to dev CLI #8211

Merged
merged 6 commits into from
Dec 5, 2023
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
18 changes: 18 additions & 0 deletions .changeset/poor-eels-bow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
"@remix-run/dev": patch
---

Add `vite:dev` and `vite:build` commands to the Remix CLI.

In order to handle upcoming Remix features where your plugin options can impact the number of Vite builds required, you should now run your Vite `dev` and `build` processes via the Remix CLI.

```diff
{
"scripts": {
- "dev": "vite dev",
- "build": "vite build && vite build --ssr"
+ "dev": "remix vite:dev",
+ "build": "remix vite:build"
}
}
```
14 changes: 5 additions & 9 deletions docs/future/vite.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ Vite handles imports for all sorts of different file types, sometimes in ways th
#### Migrating from Remix App Server

If you were using `remix-serve` in development (or `remix dev` without the `-c` flag), you'll need to switch to the new minimal dev server.
It comes built-in with the Remix Vite plugin and will take over when you run `vite dev`.
It comes built-in with the Remix Vite plugin and will take over when you run `remix vite:dev`.

Unlike `remix-serve`, the Remix Vite plugin doesn't install any [global Node polyfills][global-node-polyfills] so you'll need to install them yourself if you were relying on them. The easiest way to do this is by calling `installGlobals` at the top of your Vite config.

Expand All @@ -175,8 +175,8 @@ You'll also need to update to the new build output paths, which are `build/serve
```json filename=package.json lines=[3-4]
{
"scripts": {
"build": "vite build && vite build --ssr",
"dev": "vite dev",
"dev": "remix vite:dev",
"build": "remix vite:build",
"start": "remix-serve ./build/server/index.js"
}
}
Expand Down Expand Up @@ -272,8 +272,8 @@ app.listen(port, () =>
```json filename=package.json
{
"scripts": {
"build": "vite build && vite build --ssr",
"dev": "node ./server.mjs",
"build": "remix vite:build",
"start": "cross-env NODE_ENV=production node ./server.mjs"
}
}
Expand Down Expand Up @@ -793,11 +793,7 @@ Alternatively, you can use separate Vite config files for each tool.
For example, to use a Vite config specifically scoped to Remix:

```shellscript nonumber
# Development
vite dev --config vite.config.remix.ts

# Production
vite build --config vite.config.remix.ts && vite build --config vite.config.remix.ts --ssr
remix vite:dev --config vite.config.remix.ts
```

## Acknowledgements
Expand Down
64 changes: 27 additions & 37 deletions integration/helpers/create-fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import fse from "fs-extra";
import express from "express";
import getPort from "get-port";
import dedent from "dedent";
import resolveBin from "resolve-bin";
import stripIndent from "strip-indent";
import serializeJavaScript from "serialize-javascript";
import { sync as spawnSync, spawn } from "cross-spawn";
Expand All @@ -22,8 +21,6 @@ import { installGlobals } from "../../build/node_modules/@remix-run/node/dist/in
const TMP_DIR = path.join(process.cwd(), ".tmp", "integration");
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));

const viteBin = resolveBin.sync("vite");

export interface FixtureInit {
buildStdio?: Writable;
sourcemap?: boolean;
Expand Down Expand Up @@ -315,43 +312,36 @@ function build(

let remixBin = "node_modules/@remix-run/dev/dist/cli.js";

let commands: string[][] =
let buildArgs: string[] =
compiler === "vite"
? [
[viteBin, "build"],
[viteBin, "build", "--ssr"],
]
: [[remixBin, "build", ...(sourcemap ? ["--sourcemap"] : [])]];

commands.forEach((buildArgs) => {
let buildSpawn = spawnSync("node", buildArgs, {
cwd: projectDir,
env: {
...process.env,
NODE_ENV: mode || ServerMode.Production,
},
});
? [remixBin, "vite:build"]
: [remixBin, "build", ...(sourcemap ? ["--sourcemap"] : [])];

let buildSpawn = spawnSync("node", buildArgs, {
cwd: projectDir,
env: {
...process.env,
NODE_ENV: mode || ServerMode.Production,
},
});

// These logs are helpful for debugging. Remove comments if needed.
// console.log("spawning node " + buildArgs.join(" ") + ":\n");
// console.log(" STDOUT:");
// console.log(" " + buildSpawn.stdout.toString("utf-8"));
// console.log(" STDERR:");
// console.log(" " + buildSpawn.stderr.toString("utf-8"));

if (buildStdio) {
buildStdio.write(buildSpawn.stdout.toString("utf-8"));
buildStdio.write(buildSpawn.stderr.toString("utf-8"));
buildStdio.end();
}
// These logs are helpful for debugging. Remove comments if needed.
// console.log("spawning node " + buildArgs.join(" ") + ":\n");
// console.log(" STDOUT:");
// console.log(" " + buildSpawn.stdout.toString("utf-8"));
// console.log(" STDERR:");
// console.log(" " + buildSpawn.stderr.toString("utf-8"));

if (buildStdio) {
buildStdio.write(buildSpawn.stdout.toString("utf-8"));
buildStdio.write(buildSpawn.stderr.toString("utf-8"));
buildStdio.end();
}

if (buildSpawn.error || buildSpawn.status) {
console.error(buildSpawn.stderr.toString("utf-8"));
throw (
buildSpawn.error || new Error(`Build failed, check the output above`)
);
}
});
if (buildSpawn.error || buildSpawn.status) {
console.error(buildSpawn.stderr.toString("utf-8"));
throw buildSpawn.error || new Error(`Build failed, check the output above`);
}
}

async function writeTestFiles(init: FixtureInit, dir: string) {
Expand Down
4 changes: 2 additions & 2 deletions integration/helpers/vite-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"sideEffects": false,
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build && vite build --ssr",
"dev": "remix vite:dev",
"build": "remix vite:build",
"start": "remix-serve ./build/server/index.js",
"typecheck": "tsc"
},
Expand Down
23 changes: 7 additions & 16 deletions integration/helpers/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import type { Readable } from "node:stream";
import url from "node:url";
import execa from "execa";
import fse from "fs-extra";
import resolveBin from "resolve-bin";
import stripIndent from "strip-indent";
import waitOn from "wait-on";
import getPort from "get-port";
import shell from "shelljs";
import glob from "glob";

const remixBin = "node_modules/@remix-run/dev/dist/cli.js";
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));

export const VITE_CONFIG = async (args: {
Expand Down Expand Up @@ -127,20 +127,11 @@ const createDev =

export const viteBuild = ({ cwd }: { cwd: string }) => {
let nodeBin = process.argv[0];
let viteBin = resolveBin.sync("vite");
let commands = [
[viteBin, "build"],
[viteBin, "build", "--ssr"],
];
let results = [];
for (let command of commands) {
let result = spawnSync(nodeBin, command, {
cwd,
env: { ...process.env },
});
results.push(result);
}
return results;

return spawnSync(nodeBin, [remixBin, "vite:build"], {
cwd,
env: { ...process.env },
});
};

export const viteRemixServe = async ({
Expand Down Expand Up @@ -168,7 +159,7 @@ export const viteRemixServe = async ({
};
};

export const viteDev = createDev([resolveBin.sync("vite"), "dev"]);
export const viteDev = createDev([remixBin, "vite:dev"]);
export const customDev = createDev(["./server.mjs"]);

function node(args: string[], options: { cwd: string }) {
Expand Down
5 changes: 2 additions & 3 deletions integration/vite-dev-custom-entry-test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { test, expect } from "@playwright/test";
import type { Readable } from "node:stream";
import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
import resolveBin from "resolve-bin";
import getPort from "get-port";
import waitOn from "wait-on";

Expand Down Expand Up @@ -130,8 +129,8 @@ test.describe("Vite custom entry dev", () => {
});

let nodeBin = process.argv[0];
let viteBin = resolveBin.sync("vite");
devProc = spawn(nodeBin, [viteBin, "dev"], {
let remixBin = "node_modules/@remix-run/dev/dist/cli.js";
devProc = spawn(nodeBin, [remixBin, "vite:dev"], {
cwd: projectDir,
env: process.env,
stdio: "pipe",
Expand Down
5 changes: 2 additions & 3 deletions integration/vite-dev-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { Readable } from "node:stream";
import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
import fs from "node:fs/promises";
import path from "node:path";
import resolveBin from "resolve-bin";
import getPort from "get-port";
import waitOn from "wait-on";

Expand Down Expand Up @@ -264,8 +263,8 @@ test.describe("Vite dev", () => {
});

let nodeBin = process.argv[0];
let viteBin = resolveBin.sync("vite");
devProc = spawn(nodeBin, [viteBin, "dev"], {
let remixBin = "node_modules/@remix-run/dev/dist/cli.js";
devProc = spawn(nodeBin, [remixBin, "vite:dev"], {
cwd: projectDir,
env: process.env,
stdio: "pipe",
Expand Down
5 changes: 2 additions & 3 deletions integration/vite-dot-client-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@ test("Vite / client code excluded from server bundle", async () => {
}
`,
});
let [client, server] = viteBuild({ cwd });
expect(client.status).toBe(0);
expect(server.status).toBe(0);
let { status } = viteBuild({ cwd });
expect(status).toBe(0);
let lines = grep(
path.join(cwd, "build/server"),
/CLIENT_ONLY_FILE|CLIENT_ONLY_DIR/
Expand Down
34 changes: 16 additions & 18 deletions integration/vite-dot-server-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ test("Vite / .server file / named import in client fails with expected error", a
}
`,
});
let client = viteBuild({ cwd })[0];
let stderr = client.stderr.toString("utf8");
let result = viteBuild({ cwd });
let stderr = result.stderr.toString("utf8");
expect(stderr).toMatch(
`"dotServerFile" is not exported by "app/utils.server.ts"`
);
Expand All @@ -45,8 +45,8 @@ test("Vite / .server file / namespace import in client fails with expected error
}
`,
});
let client = viteBuild({ cwd })[0];
let stderr = client.stderr.toString("utf8");
let result = viteBuild({ cwd });
let stderr = result.stderr.toString("utf8");
expect(stderr).toMatch(
`"dotServerFile" is not exported by "app/utils.server.ts"`
);
Expand All @@ -64,8 +64,8 @@ test("Vite / .server file / default import in client fails with expected error",
}
`,
});
let client = viteBuild({ cwd })[0];
let stderr = client.stderr.toString("utf8");
let result = viteBuild({ cwd });
let stderr = result.stderr.toString("utf8");
expect(stderr).toMatch(`"default" is not exported by "app/utils.server.ts"`);
});

Expand All @@ -81,8 +81,8 @@ test("Vite / .server dir / named import in client fails with expected error", as
}
`,
});
let client = viteBuild({ cwd })[0];
let stderr = client.stderr.toString("utf8");
let result = viteBuild({ cwd });
let stderr = result.stderr.toString("utf8");
expect(stderr).toMatch(
`"dotServerDir" is not exported by "app/.server/utils.ts"`
);
Expand All @@ -100,8 +100,8 @@ test("Vite / .server dir / namespace import in client fails with expected error"
}
`,
});
let client = viteBuild({ cwd })[0];
let stderr = client.stderr.toString("utf8");
let result = viteBuild({ cwd });
let stderr = result.stderr.toString("utf8");
expect(stderr).toMatch(
`"dotServerDir" is not exported by "app/.server/utils.ts"`
);
Expand All @@ -119,8 +119,8 @@ test("Vite / .server dir / default import in client fails with expected error",
}
`,
});
let client = viteBuild({ cwd })[0];
let stderr = client.stderr.toString("utf8");
let result = viteBuild({ cwd });
let stderr = result.stderr.toString("utf8");
expect(stderr).toMatch(`"default" is not exported by "app/.server/utils.ts"`);
});

Expand All @@ -142,9 +142,8 @@ test("Vite / `handle` with dynamic imports as an escape hatch for server-only co
}
`,
});
let [client, server] = viteBuild({ cwd });
expect(client.status).toBe(0);
expect(server.status).toBe(0);
let { status } = viteBuild({ cwd });
expect(status).toBe(0);

let lines = grep(
path.join(cwd, "build/client"),
Expand Down Expand Up @@ -186,9 +185,8 @@ test("Vite / dead-code elimination for server exports", async () => {
}
`,
});
let [client, server] = viteBuild({ cwd });
expect(client.status).toBe(0);
expect(server.status).toBe(0);
let { status } = viteBuild({ cwd });
expect(status).toBe(0);

let lines = grep(
path.join(cwd, "build/client"),
Expand Down
9 changes: 4 additions & 5 deletions integration/vite-route-exports-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ test("Vite / invalid route exports / expected build error", async () => {
export const invalid2 = 2;
`,
});
let client = viteBuild({ cwd })[0];
let stderr = client.stderr.toString("utf8");
let result = viteBuild({ cwd });
let stderr = result.stderr.toString("utf8");
expect(stderr).toMatch(
"2 invalid route exports in `routes/fail-non-remix-exports.tsx`:\n - `invalid1`\n - `invalid2`"
);
Expand Down Expand Up @@ -64,7 +64,6 @@ test("Vite / invalid route exports / ignore in mdx", async () => {
# Hello World
`,
});
let [client, server] = viteBuild({ cwd });
expect(client.status).toBe(0);
expect(server.status).toBe(0);
let { status } = viteBuild({ cwd });
expect(status).toBe(0);
});
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"@types/react-test-renderer": "^18.0.0",
"@types/resolve-bin": "^0.4.1",
"@types/retry": "^0.12.0",
"@types/semver": "^7.3.4",
"@types/serialize-javascript": "^5.0.2",
Expand Down Expand Up @@ -118,7 +117,6 @@
"remark-gfm": "3.0.1",
"remark-parse": "^10.0.1",
"remark-stringify": "^10.0.2",
"resolve-bin": "^1.0.1",
"rollup": "^2.36.1",
"rollup-plugin-copy": "^3.3.0",
"semver": "^7.3.7",
Expand Down
Loading