我有一个使用 Node、Koa 和 Preact 构建的基本全栈应用程序。我正在尝试让 Preact 路由正常工作。我为
About
页面创建了一个组件和路由。当我启动 Preact 开发服务器时,我可以在 /about
成功访问 localhost:5173/about
页面。
问题是,当我启动节点服务器时,当我尝试转到
Not Found
时,我得到 localhost:8080/about
。不过,我可以通过转到 /
来成功渲染主页。
(根)index.js
const server = require('./server');
const port = 8080;
server.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
服务器\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;
客户端\src\pages\home\index.jsx
export function Home() {
return (
<h1>Preact App Homepage</h1>
);
}
客户端\src\页面约\index.jsx
export function About() {
return (
<h1>About Page</h1>
);
}
客户端\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} />);
}
客户端\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>
看来您可能有两个不同的问题:
/
Koa 问题非常简单:它在静态输出中查找与提供的 URL 匹配的 HTML 文件,当找不到任何内容时,它会返回 404。但是,这本质上只是一个问题,因为您缺少HTML 内容。您可能希望将 Koa 配置为在找不到 HTML 时将所有流量路由为
/404
,或者可能是 /
,但这非常主观。 Koa 默认提供它自己的 Not Found
响应,您可能需要考虑覆盖它,但这不是这里的主要问题。
至于预渲染,
@preact/preset-vite
中的 Preact 预渲染器(完全公开:我写的)将抓取您的应用程序以查找预渲染的链接。本质上,它将渲染 /
,读取生成的 HTML,并提取 (<a href="/about">About Us</a>
-> /about
) 中的链接以继续预渲染,在所有页面都已预渲染并且找不到更多链接后停止。然而,如果您尚未实际链接到您想要预渲染的路线,这可能会成为一个问题;通常,您会在错误页面中看到这一点,因为您可能不会链接到(比如说)/404
或/500
,但您可能希望它们都预渲染。
在默认的预渲染模板中,我们添加了标题链接(您尚未在此处上传)以涵盖这种情况,但我猜您已经删除了它们,因此
/about
页面未预渲染。
要解决此问题,您有两种选择:
additionalPrerenderRoutes
插件选项显式添加页面// vite.config.js
export default defineConfig({
plugins: [
preact({
prerender: {
enabled: true,
// ...
additionalPrerenderRoutes: ['/about', '/error-page', '...']
}
})
]
});