React/Vue 项目在 GitHub Pages 上部署时资源的路径问题
GitHub Pages 常被用来部署个人博客,而无论是大名鼎鼎的 Jekyll,还是 Hugo 或者 Hexo,他们都是将我们的文章嵌入模板,发布为静态页面,也就是说,GitHub Pages (Gitee Pages) 只支持托管静态页面,包括页面所需的静态资源。
如我们所知, React 和 Vue 都包含一个对应的路由插件,而这个路由插件会有两种模式: Hash 模式 和 History 模式。关于两者最的基本区别可以参考 Vue-Router 中的描述,下一段是阐述,熟悉 Router 的话可以跳过。
React 和 Vue 的路由旨在使得构建单页面应用更加方便。单页面应用中各屏展示的内容其实是由 JavaScript 渲染完成,所以,以 Vue 的 History 模式为例, 假设天才程序猿王花花的 GitHub 账号为 http://whh.github.io/
,他写了一个 Vue 音乐应用并上传到仓库 http://whh.github.io/music
,其中的 “关于” 页面是 /about
,当我们访问该页面时,我们的页面并未直接向后台发送请求,而浏览器的地址栏中却看似已经 “跳转” 到该页面了,显示为 http://whh.github.io/about
。
接着,我们简单提一下 GitHub Pages。我们将项目分为两类:项目名为 用户名.github.io
,普通项目。前者发布后的地址为 https://用户名.github.io/
,后者的地址为 https://用户名.github.io/项目名
。
当我们将 Vue 打包好的 /dist
文件夹作为 GitHub Pages 的目录时,如果该项目为上述第二种,我们会发现王花花的 “关于” 页面的资源地址为 /css/xxx.css
,即浏览器请求的地址为 http://whh.github.io/css/xxx.css
,而我们的资源实际的存放地址为http://whh.github.io/music/css/xxx.css
,因为我们的 css 文件在 music 项目下,这时就会有问题了。
因为打包后页面中的资源链接地址 /css/xxx.css
是绝对路径,找到问题后,我们可以将地址改为相对路径 ./css/xxx.css
,在 Vue 最新的脚手架工具 @vue/cli 3.0+
中,我们可以通过配置 vue.config.js
文件来修改 baseUrl
为 './'
,在 React 中可以修改 PUBLIC_URL
,找到 node_modules/react-script/config/paths.js
中如下一段:
function getServedPath(appPackageJson) {
const publicUrl = getPublicUrl(appPackageJson);
const servedUrl =
envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/
');
return ensureSlash(servedUrl, true);
}
把 '/'
改为 './'
即可。然后再次打包。
不理智的建议:其实你也可以根据项目名去更改 baseUrl
和 PUBLIC_URL
。
哈希模式 实际上是一样的,资源的路径也需要修改一下。
但是当我们的项目是类似以 whh.github.io
命名时,就不需要考虑该问题,因为这个项目的 GitHub Pages 所需的资源就在根目录下,而不是在二级目录 https://whh.github.io/music
中,体会一下。