github page部署react项目遇到的坑

想把自己写好的react项目放到github page上展示,没想到踩了一路的坑,好不容易解决了,记录一下免得下次又忘了。

一切都正常的步骤

安装 gh-pages 依赖

react项目中安装 gh-pages 依赖

修改package.json文件

在 package.json文件中配置homepage和scripts命令

1
"homepage": "https://yourUserName.github.io/ReactAppName/",

yourUserName为github账户名称 ReactAppName 为 仓库名

scripts 中配置:

1
"deploy": "gh-pages -d build"

依次执行命令

依次执行打包、新建gh-pages分支的命令:

1
2
npm run build
npm run deploy

访问生成的github page

github的仓库中找到setting,里面有github pages,会提示你生成的网页:
1
https://yourUserName.github.io/ReactAppName/

yourUserName为github账户名称 ReactAppName 为 仓库名

本地react项目改动后

记得重新打包静态文件部署一下,保证线上线下环境一致。

1
2
npm run build
npm run deploy

坑来了

二级域名错误(页面跳转出错)

index.html正常显示,但是我期望的二级域名应该是yourUserName.github.io/ReactAppName/,这里生成的却是yourUserName.github.io,这导致我点击项目中的“首页”永远不是跳转项目首页而是跳转我的博客首页(我的博客时搭建在github page上的)

原因:react-router的basename问题

  • react-router中默认的basename是domain,但**在githubpage部署时,其地址为”domain/ReactAppName”**。
  • 所以我们的路由都在ReactAppName下可实际上漏了一个ReactAppName。

解决方法:设置BrowserRouter的basename属性

  • 在使用react-router的BrowserRouter时,手动加上basename:

    1
    <BrowserRouter basename="/ReactAppName">    {/* ReactAppName 为 仓库名 */}
  • 但是加上以后本地或者build后运行起来路径就不对了,可以手动使用process.env.NODE_ENV来判断当前环境,给生产环境和开发环境设置不同的basename(注意别给basename设置为空了,默认的basename是domain)


axios的请求路径错误(假数据获取不到)

页面是正常显示了,页面跳转的路径没问题了,可是通过axios获取的假数据获取不到。

原因:axios请求地址错误

  • 页面跳转的路径没问题了,可是axios请求的路径还是从domain出发的,而假数据我是放在domain/ReactAppName下的(在build之前假数据在public文件夹下,build后在gh-pages分支的仓库根目录中)
  • 请求报404错误:GET https://huanglizhu.github.io/api/headerList.json 404,它是去请求了https://yourUserName.github.io/假数据路径,漏了重要的ReactAppName
  • 很明显我希望axios发出的请求路径https://huanglizhu.github.io/ChuangXiang/api/headerList.json,即https://yourUserName.github.io/ReactAppName/假数据路径

解决方法1:环境变量判断不同的请求路径

在axios请求路径中使用process.env.NODE_ENV判断来给予不同的请求路径,开发环境下给正常的请求路径,生产环境下给原本的请求路径前加上 仓库名,比如:

1
2
3
4
5
6
7
8
9
10
11
12
// 开发环境下的请求地址
let getUrl="/api/headerList.json";
// 生产环境下的请求地址
if(process.env.NODE_ENV === 'production' ){
getUrl="/ChuangXiang/api/headerList.json" // ChuangXiang是ReactAppName
}
axios.get(getUrl).then((res) => {
const data = res.data;
dispatch(changeList(data.data));
}).catch(() => {
console.log("error");
});

解决方法2:使用baseUrl

也可以使用axios的baseURL或axios.defaults.baseURL,搭配环境变量,在生产环境时设置baseURL/ChuangXiang
可参考axios文档进行配置。


后记

设置后的build的请求路径就都不对了,有时间再改吧。
本地运行页面正常显示,axios报错:
axios报错