You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

仅首页可渲染,其他页面无法访问——Node+Koa+Preact路由问题

问题描述

我使用Node、Koa和Preact构建了一个基础全栈应用,正在配置Preact路由。我为About页面创建了组件和路由,启动Preact开发服务器时,可在localhost:5173/about成功访问该页面。但启动Node服务器后,访问localhost:8080/about时出现"Not Found"错误,不过访问/路径可成功渲染首页。

相关代码

(root) index.js

const server = require('./server');

const port = 8080;

server.listen(port, () => {
  console.log(`Server listening on port ${port}`);
});

server\index.js

const Koa = require('koa');
const serve = require('koa-static');
const path = require('path');

const server = new Koa();

// Serve static files
server.use(serve(path.join(__dirname, '../client/dist')));

module.exports = server;

client\src\pages\home\index.jsx

export function Home() {
    return (
        <h1>Preact App Homepage</h1>
    );
}

client\src\pages\about\index.jsx

export function About() {
    return (
        <h1>About Page</h1>
    );
}

client\src\index.jsx

import { LocationProvider, Router, Route, hydrate, prerender as ssr } from 'preact-iso';
import { Header } from './components/Header.jsx';
import { Home } from './pages/Home/index.jsx';
import { About } from './pages/_about.jsx'; // 路径错误
import { NotFound } from './pages/_404.jsx';
import './style.css';

export function App() {
    return (
        <LocationProvider>
            <Header />
            <main>
                <Router>
                    <Route path="/" component={Home} />
                    <Route path="/about" component={About} />
                    <Route default component={NotFound} />
                </Router>
            </main>
        </LocationProvider>
    );
}

if (typeof window !== 'undefined') {
    hydrate(<App />, document.getElementById('app'));
}

export async function prerender(data) {
    return await ssr(<App {...data} />);
}

client\dist\index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" >
        <link rel="icon" type="image/svg+xml" href="/vite.svg" >
        <meta name="viewport" content="width=device-width, initial-scale=1.0" >
        <meta name="color-scheme" content="light dark" >
        <title>Vite + Preact</title>
        <script type="module" crossorigin src="/assets/index-7GmgnfZn.js"></script>
        <link rel="modulepreload" crossorigin href="/assets/index-BgxwHnNi.js">
        <link rel="stylesheet" crossorigin href="/assets/index-C_LgOj56.css">
    </head>
    <body>
        <div id="app"><header><nav><a href="/" class="active">Home</a><a href="/404">404</a></nav></header><main><h1>Preact App Homepage</h1></main><script type="isodata"></script></div>
    </body>
</html>
解决方案

1. 修复Koa服务器的SPA路由 fallback

问题核心是koa-static只会返回存在的静态文件,当访问/about时,服务器找不到对应文件直接返回404;而Preact开发服务器默认开启SPA模式,所有路由请求都会指向index.html,由前端路由处理。

修改server/index.js,添加SPA fallback中间件:

const Koa = require('koa');
const serve = require('koa-static');
const path = require('path');
const fs = require('fs').promises;

const server = new Koa();

// 静态资源服务
server.use(serve(path.join(__dirname, '../client/dist'), {
  maxage: process.env.NODE_ENV === 'production' ? 3600000 : 0 // 生产环境缓存1小时,开发环境无缓存
}));

// SPA fallback:静态资源不存在时返回index.html
server.use(async (ctx) => {
  try {
    const indexPath = path.join(__dirname, '../client/dist/index.html');
    const content = await fs.readFile(indexPath, 'utf8');
    ctx.type = 'html';
    ctx.body = content;
  } catch (err) {
    ctx.status = 404;
    ctx.body = 'Not Found';
  }
});

module.exports = server;

2. 修复About组件的导入路径

client/src/index.jsx中About组件的导入路径错误,修正为实际文件路径:

// 修改前
import { About } from './pages/_about.jsx';
// 修改后
import { About } from './pages/about/index.jsx';

完成修改后,重新执行前端打包命令(npm run build),再启动Node服务器,访问localhost:8080/about即可正常加载页面。

内容的提问来源于stack exchange,提问作者bprdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 00:41:06