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

Parcel构建后Preact Router无法正常工作的问题求助

Preact + Parcel 构建后子路由404问题解决方法

问题场景

用Parcel搭建Preact项目,开发环境npm run dev下点击My Profile链接跳转正常,但执行npm run build部署dist目录后,直接访问http://localhost:8080/profile出现404,前端路由失效。

相关代码

index.js

import { h, render } from 'preact';
import Router from 'preact-router';

const Home = ()=> (<h2>Home</h2>);
const MyProfile = () => <h2>My Profile</h2>;

function App() {
  return (
    <div>
      <nav>
        <a href="/">Home</a>
        <a href="/profile">My Profile</a>
      </nav>
      <br></br>
      <Router>
        <Home path="/" />
        <MyProfile path="/profile" />
      </Router>
    </div>
  );
}

render(<App />, document.body);

package.json

{
  "name": "test-preact-router",
  "version": "1.0.0",
  "description": "",
  "source": "index.html",
  "scripts": {
    "dev": "npx parcel -p 8080",
    "build": "npx parcel build"
  },
  "alias": {
    "preact/jsx-dev-runtime": "preact/jsx-runtime"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "parcel": "^2.9.3",
    "preact": "^10.15.1",
    "preact-router": "^4.1.1"
  }
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="container"></div>
  <script type="module" src="./index.js"></script>
</body>
</html>

问题原因

这是单页应用(SPA)的典型问题:

  • 开发环境中,Parcel内置的开发服务器会自动将所有路由请求转发到index.html,让前端路由去解析路径。
  • 生产部署时,服务器默认会尝试寻找/profile对应的物理文件,但SPA只有一个入口文件index.html,所以返回404。

解决方案

方案1:配置服务器 fallback 规则(推荐,保持干净URL)

不管用哪种服务器部署,核心是让所有路由请求都转发到index.html:

  • 用serve工具部署:
    先安装serve:npm install -g serve
    部署命令改为:serve -s dist
    -s参数会让所有找不到的请求 fallback 到index.html。

  • Nginx部署:
    修改Nginx配置文件,添加规则:

    location / {
      try_files $uri $uri/ /index.html;
    }
    
  • Apache部署:
    在dist目录创建.htaccess文件,内容如下:

    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
    

方案2:修改Parcel构建配置(配合静态托管)

修改package.json中的build命令,添加--public-url ./,确保资源路径为相对路径:

"scripts": {
  "dev": "npx parcel -p 8080",
  "build": "npx parcel build --public-url ./"
}

此方案需要配合服务器的fallback规则一起使用。

方案3:改用Hash路由(快速解决,URL带#)

修改preact-router为hash模式,这样服务器只会解析到根路径,路由由前端处理:

function App() {
  return (
    <div>
      <nav>
        <a href="#/">Home</a>
        <a href="#/profile">My Profile</a>
      </nav>
      <br></br>
      <Router hash>
        <Home path="/" />
        <MyProfile path="/profile" />
      </Router>
    </div>
  );
}

此时URL会变为http://localhost:8080/#/profile,不会触发服务器的404。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:53:20