1.项目完成后直接npm run build 后发现资源找不到,chunk.css,js等全部是报错。
解决办法,在page.json文件里面增加一行:"homepage": "./",
2.由于项目不是直接放在服务器根目录,放在二级子目录,导致路由无法匹配。指向错误页面。或者空白。
解决方法:
react路由使用BrowserRouter ,里面增加一个属性basename,相当于基准url。不是默认的根路径
我的文件位置/WEB/reactdemo,
:打开页面浏览器显示的地址:http://localhost/WEB/reactdemo/home
3.部署后刷新出现无法找到not found的404问题
(以下内容为摘抄参考:React-Router browserHistory浏览器刷新出现页面404解决方案_hsany330的专栏-优快云博客)
问题分析
在刷新页面时,浏览器会向服务器请求localhost:8000/page1,服务器会去根目录下查找page1.html文件,发现找不到该文件,而服务器上实际上没有该物理路径,所有的路由页面实际上是根据react-router去渲染的,所以才会报404
第二案例分析
当刷新页面时,浏览器会向服务器请求example.com/list
,服务器实际会去找根目录下list.html
这个文件,发现找不到,因为实际上我们的服务器并没有这样的 物理路径/文件 或没有配置处理这个路由,所有内容都是通过React-Router去渲染React组件,自然会报404错误。这种情况我们可以通过配置Nginx或通过自建Node服务器来解决。
Nginx方式
采用Nginx方案需要先将所有资源打包生成到对应的目录,比如dist
,然后做如下配置:
-
server {
-
server_name react.thinktxt.com;
-
listen 80;
-
root /Users/txBoy/WEB-Project/React-Demo/dist;
-
index index.html;
-
location / {
-
try_files $uri /index.html;
-
}
-
}
通过配置Nginx,访问任何URI都指向index.html,浏览器上的path,会自动被React-router处理,进行无刷新跳转。
通过修改webpack-dev-server运行方式
这个解决方法很简单,直接在运行时加入参数“–history-api-fallback”就可以了。我们修改package.json相关的代码:
-
"scripts": {
-
"build": "webpack",
-
"dev": "webpack-dev-server --inline --devtool eval --progress --colors --hot --content-base ./build --history-api-fallback"
-
},
Node服务端配置
一个express应用的配置示例:
-
const express = require('express');
-
const path = require('path');
-
const port = process.env.PORT || 8080;
-
const app = express();
-
//加载指定目录静态资源
-
app.use(express.static(__dirname + '/dist'))
-
//配置任何请求都转到index.html,而index.html会根据React-Router规则去匹配任何一个route
-
app.get('*', function (request, response){
-
response.sendFile(path.resolve(__dirname, 'dist', 'index.html'))
-
})
-
app.listen(port, function () {
-
console.log("server started on port " + port)
-
})
一个Koa应用的配置示例:
-
import Koa from 'koa';
-
import xtpl from 'koa-xtpl';
-
import path from 'path';
-
const app = new Koa();
-
const port = process.env.PORT || 8081;
-
app.use(xtpl({
-
root: path.resolve(__dirname, '../dist'),
-
extname: 'html',
-
commands: {}
-
}));
-
app.use(async(ctx, next) => {
-
await ctx.render('index', {});
-
});
-
app.listen(port, () => {
-
console.log('Server started on port' + port);
-
});
注意: 由于koa的这种方式端口与webpack-dev-server(8080)必须不同,所以还需要配合Nginx代理。例如:
-
server {
-
server_name react.thinktxt.com;
-
listen 80;
-
location / {
-
proxy_pass http://localhost:8081;
-
}
-
}
-
server {
-
server_name static.react.thinktxt.com;
-
listen 80;
-
location / {
-
proxy_pass http://localhost:8080;
-
}
-
}
既然我们的Nginx代理用了真实域名,自然别忘了修改一下host,如下:
-
127.0.0.1 react.thinktxt.com
-
127.0.0.1 static.react.thinktxt.com
这样我们就大功告成了,可以happy的在地址栏直接访问任何采用browserHistory方式配置的路由页面了。
总结
面对这种场景其实还有很多种方案,任何服务端的处理方式都可以,例如还有PHP、Apache等等。
其本质的原理就是利用服务端将任何请求都指向
index.html
,而在React应用中index.html又刚好通过React-Router配置了相应的路由,我们让服务器返回index.html,后面就交给前端路由来实现无刷新加载对应页面。