Skip to content

Commit

Permalink
fix: render function dynamic router match error (#5831)
Browse files Browse the repository at this point in the history
  • Loading branch information
GiveMe-A-Name committed Jun 17, 2024
1 parent da84b0a commit 8cdb67d
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 5 deletions.
6 changes: 6 additions & 0 deletions .changeset/plenty-ducks-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@modern-js/server-core': patch
---

fix: render function dynamic router match error
fix: render 函数动态路由匹配错误
20 changes: 18 additions & 2 deletions packages/server/core/src/base/middlewares/renderHandler/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,28 @@ interface CreateRenderOptions {
nonce?: string;
}

const DYNAMIC_ROUTE_REG = /\/:./;

function getRouter(routes: ServerRoute[]): Router<ServerRoute> {
const sorted = routes.sort(sortRoutes);
const dynamicRoutes: ServerRoute[] = [];
const normalRoutes: ServerRoute[] = [];

routes.forEach(route => {
if (DYNAMIC_ROUTE_REG.test(route.urlPath)) {
dynamicRoutes.push(route);
} else {
normalRoutes.push(route);
}
});

const finalRoutes = [
...normalRoutes.sort(sortRoutes),
...dynamicRoutes.sort(sortRoutes),
];

const router = new TrieRouter<ServerRoute>();

for (const route of sorted) {
for (const route of finalRoutes) {
const { urlPath: originUrlPath } = route;

const urlPath = originUrlPath.endsWith('/')
Expand Down
43 changes: 40 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions tests/integration/routes-match/modern.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { appTools, defineConfig } from '@modern-js/app-tools';

const bundler = process.env.BUNDLER;

export default defineConfig({
plugins: [
appTools({
bundler: bundler === 'rspack' ? 'experimental-rspack' : 'webpack',
}),
],
runtime: {
router: false,
state: false,
},
server: {
ssr: true,
routes: {
a: '/detail/:id',
b: '/detail/1',
c: '/detail/12',
},
},
});
34 changes: 34 additions & 0 deletions tests/integration/routes-match/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"private": true,
"name": "routes-match",
"version": "2.9.0",
"scripts": {
"dev": "modern dev",
"build": "modern build",
"serve": "modern serve",
"new": "modern new",
"lint": "modern lint"
},
"engines": {
"node": ">=14.17.6"
},
"eslintIgnore": [
"node_modules/",
"dist/"
],
"dependencies": {
"@modern-js/runtime": "workspace:*",
"react": "^18",
"react-dom": "^18",
"fs-extra": "^10.1.0"
},
"devDependencies": {
"@modern-js/app-tools": "workspace:*",
"@types/fs-extra": "9.0.13",
"@types/node": "^14",
"@types/react": "^18",
"@types/react-dom": "^18",
"typescript": "^5",
"@types/jest": "^29"
}
}
1 change: 1 addition & 0 deletions tests/integration/routes-match/src/a/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => <div>AAA</div>;
1 change: 1 addition & 0 deletions tests/integration/routes-match/src/b/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => <div>BBB</div>;
1 change: 1 addition & 0 deletions tests/integration/routes-match/src/c/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => <div>CCC</div>;
54 changes: 54 additions & 0 deletions tests/integration/routes-match/tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import dns from 'node:dns';
import path from 'path';
import puppeteer, { Page, Browser } from 'puppeteer';
import {
launchApp,
getPort,
killApp,
launchOptions,
} from '../../../utils/modernTestUtils';

dns.setDefaultResultOrder('ipv4first');

const appDir = path.resolve(__dirname, '../');

describe('map routes match', () => {
let app: any;
let appPort: number;
let page: Page;
let browser: Browser;

beforeAll(async () => {
appPort = await getPort();
app = await launchApp(appDir, appPort, {});

browser = await puppeteer.launch(launchOptions as any);
page = await browser.newPage();
});

afterAll(async () => {
if (browser) {
browser.close();
}
if (app) {
await killApp(app);
}
});

test('should match route correctly', async () => {
const res1 = await page.goto(`http://localhost:${appPort}/detail/123`);
const text1 = await res1.text();

expect(text1).toMatch('AAA');

const res2 = await page.goto(`http://localhost:${appPort}/detail/1`);
const text2 = await res2.text();

expect(text2).toMatch('BBB');

const res3 = await page.goto(`http://localhost:${appPort}/detail/12`);
const text3 = await res3.text();

expect(text3).toMatch('CCC');
});
});
13 changes: 13 additions & 0 deletions tests/integration/routes-match/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "@modern-js/tsconfig/base",
"compilerOptions": {
"declaration": false,
"jsx": "preserve",
"baseUrl": "./",
"paths": {
"@/*": ["./src/*"],
"@shared/*": ["./shared/*"]
}
},
"include": ["src", "shared", "config"]
}

0 comments on commit 8cdb67d

Please sign in to comment.