Free Arch_ 解决静态站点 deeplink 404 的问题(以 Taro 框架举例)

哈德韦

共 2100字,需浏览 5分钟

 · 2021-10-12

FBI Warning:Free Arch 是我的杜撰,意味着应用的架构全部使用免费资源。该架构服务于像我一样的这种贫穷的个人开发者,目的是在尽可能免费的前提下,为应用打造极致的用户体验(将羊毛薅到无以复加!)。



背景


个人开发者创建的网页站点,希望开放外网访问,首先需要解决部署问题。最佳实践是将站点静态化,从而可以在大量的免费静态站点部署服务中自由选择。如果使用 GitHub 托管代码,当然建议直接使用 GitHub Pages 服务来部署静态站点。

市面上也有大量的专门的免费静态站点生成器,一般这样的部署不会碰到什么问题。但是如果采用了其他的框架开发站点,那么很容易碰到的一个问题是:可以访问首页,点击进入别的页面也没有问题。但是一旦在非首页的页面,按键刷新了页面,或者直接从 deeplink 进入,都会得到一个 404 页面,比如:



现象重述


站点静态化部署后:


站点的 deeplink 页面,从首页点击进入正常展示,直接进入或者刷新就会 404。

站点的首页没有这个问题。


站点如果采用服务器部署,则没有以上问题。比如本地开发时,实际上启动了一个服务器程序,deeplink 是可以直接打开的。


原因


生成的站点文件,根目录下有一个 index.html 文件,从而首页可以正常打开。但是 deeplink 对应的路径,在服务器上没有对应的文件。从首页上点击可以正常显示,是因为框架做了客户端路由,也就是渲染的文件仍然是服务器上根目录下的 index.html 文件,但是这个文件中加载的 javascript,处理了点击并做了后续的渲染。

在有服务器程序运行的情况下,直接打开 deeplink,页面也能正常渲染,是因为服务器程序处理了路由,并对相关的路径返回了某个 html 结果响应,从而正常显示页面。


如果没有服务器渲染程序,而 deeplink 对应的路径在服务器上又找不到响应的文件,自然就是 404 了。


解决办法


原因找到了,解决办法也很简单粗暴,在服务器上直接创建所有的 deeplink 路径就行了。当然也可以运行服务器端渲染程序解决,但这就不是 Free Arch 的范围了。


举个例子


在线演示:https://taro.pa-ca.me/pages/yuque/index


这个例子采用 Taro 框架生成了一个静态站点,通过 GitHub Actions,将 yarn build 后产生的 dist 目录部署在 GitHub pages 服务上。Taro 和很多框架一样,在 build 后生成了一个 dist 目录,但是这个目录下只有一个 index.html 文件,如果你的应用有其他路径,默认是不会为每个路径建立文件夹和相应的 html 文件的。


这里通过在 GitHub Actions 的配置文件中加入一些 shell 脚本,去为所有页面建立文件夹,并且将 dist/index.html 文件复制到相应文件夹下,从而解决了 404 的问题。


首先看下所有的客户端路由页面,在 app.config.ts 文件中:

export default {  pages: [    'pages/yuque/index',    'pages/yuque/article',    'pages/index/index',    'pages/about/index'  ],  window: ...}


除去 yarn build 会自动生成的首页对应 'pages/index/index' 路由外,其他路由都是要自行灌入 shell 脚本的:


- name: buildrun: yarn && yarn build:h5

# 在 build 完成后做一些 deeplink 工作:- name: deeplinksrun: |mkdir -p dist/pages/yuquemkdir -p dist/pages/about

cp -r dist/index.html dist/pages/yuque/index.html

# 注意,不是所有路由都对应为 index.html,但是可以复用 index.html,所以改个名即可:cp -r dist/index.html dist/pages/yuque/article.htmlcp -r dist/index.html dist/pages/about/index.html


继续改进


这个 shell 脚本虽然简单粗暴有效果,但是还可以更加简化和智能化,比如自动解析 app.config.ts 文件,这样不用每次添加新的路由时,需要改动两个地方。或者将这个零散的逻辑封装成一个 GitHub Action,命名为 ghaction-taro-pages 等等。


欢迎留言反馈更好的做法!



浏览 37
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报