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
相关产品推荐
相关产品推荐

