Skip to content

Commit 422dbe7

Browse files
www: port to vite
1 parent 1daca75 commit 422dbe7

10 files changed

Lines changed: 147 additions & 69 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ jobs:
3333
if: github.repository_owner == 'denoland'
3434
with:
3535
project: "fresh"
36-
entrypoint: "./www/_fresh/server.js"
37-
root: "."
36+
entrypoint: "server.js"
37+
root: "./www/_fresh/"

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
],
77
"tasks": {
88
"test": "deno test -A --parallel",
9-
"www": "deno task --cwd=www start",
9+
"www": "deno task --cwd=www dev",
1010
"build-www": "deno task --cwd=www build",
1111
"screenshot": "deno run -A www/utils/screenshot.ts",
1212
"check:types": "deno check --allow-import",

deno.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

www/client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "./assets/styles.css";

www/deno.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
{
22
"tasks": {
3-
"start": "deno run -A --watch=static/,routes/,../src,../docs dev.ts",
4-
"build": "deno run -A dev.ts build",
5-
"preview": "deno serve -A _fresh/server.js"
3+
"start": "deno serve -A _fresh/server.js",
4+
"dev": "vite",
5+
"build": "vite build"
6+
},
7+
"imports": {
8+
"@tailwindcss/vite": "npm:@tailwindcss/vite@^4.1.12",
9+
"vite": "npm:vite@^7.1.2",
10+
"vite-plugin-inspect": "npm:vite-plugin-inspect@^11.3.2"
611
}
712
}

www/main_test.ts

Lines changed: 74 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,100 @@
11
import VERSIONS from "../versions.json" with { type: "json" };
2-
import { app } from "./main.ts";
32
import {
4-
buildProd,
5-
withBrowserApp,
3+
withBrowser,
4+
withChildProcessServer,
65
} from "../packages/fresh/tests/test_utils.tsx";
76
import { expect } from "@std/expect";
87
import { retry } from "@std/async/retry";
8+
import { buildVite } from "../packages/plugin-vite/tests/test_utils.ts";
99

10-
const applyCache = await buildProd({ root: import.meta.dirname! });
11-
applyCache(app);
12-
13-
const handler = app.handler();
10+
const result = await buildVite(import.meta.dirname!);
1411

1512
Deno.test("CORS should not set on GET /fresh-badge.svg", async () => {
16-
const req = new Request("http://localhost/fresh-badge.svg");
17-
const resp = await handler(req);
18-
await resp?.body?.cancel();
19-
20-
expect(resp.headers.get("cross-origin-resource-policy")).toEqual(null);
13+
await withChildProcessServer(
14+
{
15+
cwd: result.tmp,
16+
args: ["serve", "-A", "--port", "0", "_fresh/server.js"],
17+
},
18+
async (address) => {
19+
const resp = await fetch(`${address}/fresh-badge.svg`);
20+
await resp?.body?.cancel();
21+
expect(resp.headers.get("cross-origin-resource-policy")).toEqual(null);
22+
},
23+
);
2124
});
2225

2326
Deno.test({
2427
name: "shows version selector",
2528
fn: async () => {
2629
await retry(async () => {
27-
await withBrowserApp(app, async (page, address) => {
28-
await page.goto(`${address}/docs`);
29-
await page.waitForSelector("#version");
30+
await withChildProcessServer(
31+
{
32+
cwd: result.tmp,
33+
args: ["serve", "-A", "--port", "0", "_fresh/server.js"],
34+
},
35+
async (address) => {
36+
await withBrowser(async (page) => {
37+
await page.goto(`${address}/docs`);
38+
await page.waitForSelector("#version");
3039

31-
// Check that we redirected to the first page
32-
await page.waitForFunction(() => {
33-
const url = new URL(window.location.href);
34-
return url.pathname === "/docs/introduction";
35-
});
40+
// Check that we redirected to the first page
41+
await page.waitForFunction(() => {
42+
const url = new URL(window.location.href);
43+
return url.pathname === "/docs/introduction";
44+
});
3645

37-
// Wait for version selector to be enabled
38-
await page.waitForSelector("#version:not([disabled])");
46+
// Wait for version selector to be enabled
47+
await page.waitForSelector("#version:not([disabled])");
3948

40-
const options = await page
41-
.locator<HTMLSelectElement>("#version")
42-
.evaluate((el) => {
43-
return Array.from(el.options).map((option) => ({
44-
value: option.value,
45-
label: option.textContent,
46-
}));
47-
});
49+
const options = await page
50+
.locator<HTMLSelectElement>("#version")
51+
.evaluate((el) => {
52+
return Array.from(el.options).map((option) => ({
53+
value: option.value,
54+
label: option.textContent,
55+
}));
56+
});
4857

49-
expect(options).toEqual([
50-
{
51-
value: "canary",
52-
label: "canary",
53-
},
54-
{
55-
value: "latest",
56-
label: VERSIONS[0],
57-
},
58-
]);
58+
expect(options).toEqual([
59+
{
60+
value: "canary",
61+
label: "canary",
62+
},
63+
{
64+
value: "latest",
65+
label: VERSIONS[0],
66+
},
67+
]);
5968

60-
const selectValue = await page
61-
.locator<HTMLSelectElement>("#version")
62-
.evaluate((el) => el.value);
63-
expect(selectValue).toEqual("latest");
69+
const selectValue = await page
70+
.locator<HTMLSelectElement>("#version")
71+
.evaluate((el) => el.value);
72+
expect(selectValue).toEqual("latest");
6473

65-
// Go to canary page
66-
await page.evaluate(() => {
67-
const el = document.querySelector("#version") as HTMLSelectElement;
68-
el.value = "canary";
69-
el.dispatchEvent(new Event("change"));
70-
});
74+
// Go to canary page
75+
await page.evaluate(() => {
76+
const el = document.querySelector(
77+
"#version",
78+
) as HTMLSelectElement;
79+
el.value = "canary";
80+
el.dispatchEvent(new Event("change"));
81+
});
7182

72-
await new Promise((r) => setTimeout(r, 1000));
83+
await new Promise((r) => setTimeout(r, 1000));
7384

74-
await page.waitForSelector("#version:not([disabled])");
75-
const selectValue2 = await page
76-
.locator<HTMLSelectElement>("#version")
77-
.evaluate((el) => el.value);
78-
expect(selectValue2).toEqual("canary");
85+
await page.waitForSelector("#version:not([disabled])");
86+
const selectValue2 = await page
87+
.locator<HTMLSelectElement>("#version")
88+
.evaluate((el) => el.value);
89+
expect(selectValue2).toEqual("canary");
7990

80-
await page.waitForFunction(() => {
81-
const url = new URL(window.location.href);
82-
return url.pathname === "/docs/canary/introduction";
83-
});
84-
});
91+
await page.waitForFunction(() => {
92+
const url = new URL(window.location.href);
93+
return url.pathname === "/docs/canary/introduction";
94+
});
95+
});
96+
},
97+
);
8598
});
8699
},
87100
});

www/routes/_app.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ export default define.page(function App({ Component, state, url }) {
3131
type="font/woff2"
3232
crossorigin="anonymous"
3333
/>
34-
<link rel="stylesheet" href={asset("/styles.css")} />
3534
{url.pathname === "/"
3635
? <link rel="stylesheet" href={asset("/prism.css")} />
3736
: null}

www/routes/docs/[...slug].tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ export const handler = define.handlers<Data>({
120120
}
121121

122122
// Parse markdown front matter
123-
const url = new URL(`../../../${entry.file}`, import.meta.url);
123+
// deno-lint-ignore no-explicit-any
124+
const url = (import.meta as any).env.PROD
125+
? new URL(`../${entry.file}`, import.meta.url)
126+
: new URL(`../../../${entry.file}`, import.meta.url);
124127
const fileContent = await Deno.readTextFile(url);
125128
const { body, attrs } = frontMatter<Record<string, unknown>>(fileContent);
126129

www/vite.config.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { defineConfig, type Plugin } from "vite";
2+
import { fresh } from "@fresh/plugin-vite";
3+
import tailwindcss from "@tailwindcss/vite";
4+
import inspect from "vite-plugin-inspect";
5+
import { copy } from "@std/fs";
6+
import * as path from "@std/path";
7+
8+
export default defineConfig({
9+
plugins: [
10+
fresh(),
11+
tailwindcss(),
12+
inspect(),
13+
copyDocs(),
14+
],
15+
});
16+
17+
function copyDocs(): Plugin {
18+
let serverOutDir = "";
19+
20+
return {
21+
name: "fresh:copy-docs",
22+
configResolved(config) {
23+
serverOutDir = config.environments.ssr.build.outDir;
24+
},
25+
async writeBundle() {
26+
const branches = ["canary", "latest"];
27+
28+
for (const branch of branches) {
29+
const source = path.join(import.meta.dirname!, "..", "docs", branch);
30+
const target = path.join(serverOutDir, "docs", branch);
31+
32+
try {
33+
await Deno.remove(target, { recursive: true });
34+
} catch (err) {
35+
if (!(err instanceof Deno.errors.NotFound)) {
36+
throw err;
37+
}
38+
}
39+
40+
try {
41+
await Deno.mkdir(path.dirname(target), { recursive: true });
42+
} catch {
43+
// Ignore
44+
}
45+
46+
await copy(source, target);
47+
}
48+
},
49+
};
50+
}

0 commit comments

Comments
 (0)