Skip to content
Closed
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
22 changes: 22 additions & 0 deletions e2e/fixtures/fs-router-build-split/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "fs-router-build-split",
"version": "0.1.0",
"type": "module",
"private": true,
"scripts": {
"dev": "waku dev",
"build": "waku build",
"start": "waku start"
},
"dependencies": {
"react": "~19.2.5",
"react-dom": "~19.2.5",
"react-server-dom-webpack": "~19.2.5",
"waku": "latest"
},
"devDependencies": {
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"typescript": "^6.0.2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DYNAMIC_RENDER_SENTINEL = 'PR1974_DYNAMIC_ROUTE_RENDER_SENTINEL';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const STATIC_RENDER_SENTINEL = 'PR1974_STATIC_ROUTE_RENDER_SENTINEL';
3 changes: 3 additions & 0 deletions e2e/fixtures/fs-router-build-split/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Home() {
return <h1>Home</h1>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DYNAMIC_RENDER_SENTINEL } from '../lib/runtime-build-dynamic.js';

export default function RuntimeBuildDynamic() {
return <h1>{DYNAMIC_RENDER_SENTINEL}</h1>;
}

export const getConfig = async () => ({
render: 'dynamic' as const,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { STATIC_RENDER_SENTINEL } from '../lib/runtime-build-static.js';

export default function RuntimeBuildStatic() {
return <h1>{STATIC_RENDER_SENTINEL}</h1>;
}

export const getConfig = async () => ({
render: 'static' as const,
});
16 changes: 16 additions & 0 deletions e2e/fixtures/fs-router-build-split/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"strict": true,
"target": "esnext",
"noEmit": true,
"isolatedModules": true,
"moduleDetection": "force",
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"skipLibCheck": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"jsx": "react-jsx"
}
}
1 change: 1 addition & 0 deletions e2e/fixtures/fs-router/src/lib/runtime-build-dynamic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DYNAMIC_RENDER_SENTINEL = 'PR1974_DYNAMIC_ROUTE_RENDER_SENTINEL';
1 change: 1 addition & 0 deletions e2e/fixtures/fs-router/src/lib/runtime-build-static.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const STATIC_RENDER_SENTINEL = 'PR1974_STATIC_ROUTE_RENDER_SENTINEL';
13 changes: 13 additions & 0 deletions e2e/fixtures/fs-router/src/pages/runtime-build-dynamic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { DYNAMIC_RENDER_SENTINEL } from '../lib/runtime-build-dynamic.js';

const RuntimeBuildDynamic = () => {
return <h2>{DYNAMIC_RENDER_SENTINEL}</h2>;
};

export const getConfig = () => {
return {
render: 'dynamic',
} as const;
};

export default RuntimeBuildDynamic;
13 changes: 13 additions & 0 deletions e2e/fixtures/fs-router/src/pages/runtime-build-static.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { STATIC_RENDER_SENTINEL } from '../lib/runtime-build-static.js';

const RuntimeBuildStatic = () => {
return <h2>{STATIC_RENDER_SENTINEL}</h2>;
};

export const getConfig = () => {
return {
render: 'static',
} as const;
};

export default RuntimeBuildStatic;
76 changes: 76 additions & 0 deletions e2e/fs-router-build-split.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { existsSync, readFileSync, readdirSync } from 'node:fs';
import { join } from 'node:path';
import { expect } from '@playwright/test';
import { prepareStandaloneSetup, test } from './utils.js';

const startApp = prepareStandaloneSetup('fs-router-build-split');

const STATIC_RENDER_SENTINEL = 'PR1974_STATIC_ROUTE_RENDER_SENTINEL';
const DYNAMIC_RENDER_SENTINEL = 'PR1974_DYNAMIC_ROUTE_RENDER_SENTINEL';

const collectDistFiles = (dir: string): string[] => {
const files: string[] = [];
const queue = [dir];

while (queue.length) {
const current = queue.pop()!;
for (const entry of readdirSync(current, { withFileTypes: true })) {
const nextPath = join(current, entry.name);
if (entry.isDirectory()) {
queue.push(nextPath);
continue;
}
files.push(nextPath);
}
}

return files;
};

test.describe('fs-router build split', () => {
let port: number;
let standaloneDir: string;
let stopApp: (() => Promise<void>) | undefined;

test.beforeAll(async ({ mode }) => {
({ port, stopApp, standaloneDir } = await startApp(mode));
});

test.afterAll(async () => {
if (stopApp) {
await stopApp();
}
});

test('runtime bundle excludes fully static routes while SSG still emits them', async ({
mode,
page,
}) => {
test.skip(mode !== 'PRD');

const distDir = join(standaloneDir, 'dist');

expect(existsSync(distDir)).toBe(true);

await page.goto(`http://localhost:${port}/runtime-build-static`);
await expect(
page.getByRole('heading', { name: STATIC_RENDER_SENTINEL }),
).toBeVisible();

await page.goto(`http://localhost:${port}/runtime-build-dynamic`);
await expect(
page.getByRole('heading', { name: DYNAMIC_RENDER_SENTINEL }),
).toBeVisible();

const serverDistFiles = collectDistFiles(join(distDir, 'server'));
const serverJsContents = serverDistFiles
.filter((file) => file.endsWith('.js'))
.map((file) => readFileSync(file, 'utf8'));

expect(
serverJsContents.some((content) =>
content.includes(STATIC_RENDER_SENTINEL),
),
).toBe(false);
});
});
Loading
Loading