使用 Cloudflare Pages 部署静态网站
2022-07-06 · 1,766 chars · 9 min read
2021 年年底的时候,我通过 web archive 找回了所有网站页面,重新整理并使用 react + SSG 的方式,搭建了当前这个站点。最开始的时候是部署在 vercel 上的,整体用起来还是很方便的,但是访问速度比较尴尬,按照 vercel 官方的说明改了 DNS 解析,结果我测试发现,国内无代理可以直接访问,但是香港却不行...
虽然没有做太多实测,但是目前网上的普遍观点是,vercel 之类的小厂不太稳定,而 Github Page 国内很慢,Cloudflare 国内也一言难尽,但是整体功能性上占优。考虑了一段时间,决定还是切换到 Cloudflare Pages,希望尽可能兼顾所有用户,外加能访问到我网站的朋友,应该大部分都是码农,代理加持下速度不会太差。
最直接的使用方式#
Cloudflare Pages 提供了三种方式创建项目:
- 链接到 Git:支持 Github、GItlab
- 直接上传
- 使用 wrangler cli:支持其它的代码托管平台和 CI
我最开始用的就是直接关联 Github,创建方法非常简单就不细说了,按照它网站上的步骤一步 一步来就行了。
创建好项目之后,可以对项目进行一些设置:
大体上就是:
- 自定义域名:除了默认的
:project.pages.dev
之外,可以添加自己的域名(要先使用 Cloudflare 的 DNS) - 设置
- 常规设置:修改名称、添加成员、开启 Web Analytics 等
- 构建和部署:控制部署的分支,命令,环境等等
- 环境变量:添加环境变量,例如 node 版本就是通过
NODE_VERSION
设置的 - 函数:SSG 的静态页面,还没用过
当你设置的分支有新提交,Cloudflare Pages 就会自动触发构建和部署
你可以控制的只有两处
- 构建命令:使用什么命令构建,如
npm run build
- 文件目录:构建完的产物在哪个目录下,如
public
,dist
然后就没有然后了,能覆盖大部分“前端静态应用”的需求了。但是......
使用 Github Actions 和 wrangler#
上面讲的方式虽然简单,但是还是存在一些问题的。
首先,我想用 pnpm,我还是比较认同 pnpm 的理念的,外加 npm 又十分拉跨,导致我十分想试试 pnpm。可是上述方式会自动 的执行 npm install
,目前没得选,虽然在 build
命令里安装 pnpm 在理论上是可行的,但是却非常不“纯粹”,逼死强迫症。
其次,我用 Github Action 执行一整套 CI 操作,包括 lint、build 等,前面讲的方式,在部署的时候会 build 两次,一次在 github 一次在 cloudflare,再次逼死强迫症。
第三,构建部署和 Github Action 是同步执行的,没什么关联关系。但理想的方式肯定是等 CI 全部通过后再执行部署。
所以最佳的部署流程是,在 Github Action 里执行完所有 CI 的验证,包括 build。然后直接使用 build 的产物部署到 Cloudflare Pages。刚好,Cloudflare 提供了 wrangler 工具可以帮我们完成理想的构建流程。
wrangler 提供了官方的 action,用它来部署仅需两个 token
on: [push] jobs: deploy: runs-on: ubuntu-latest name: Deploy steps: - uses: actions/checkout@v3 - name: Publish uses: cloudflare/[email protected] with: apiToken: ${{ secrets.CF_API_TOKEN }} accountId: ${{ secrets.CF_ACCOUNT_ID }} command: pages publish --project-name=example
- CF_API_TOKEN:要自己创建,点进个人资料,找到 API 令牌创建即可
- CF_ACCOUNT_ID:这个在 dashboard-网站-概述 的右下角可以直接看到
将这两个 token 添加到 github secrets 里即可。最后按照实际需求修改 publish 命令
pages publish [DIRECTORY] --branch=main --project-name=example
特别说明下,我是使用直接上传的方式创建了一个新项目(实际上可能用 cli 更好?),他默认的生产分支是 main,必须指定分支,否则 全部部署到预览环境里。
至此,大功告成。
一些细节问题#
在使用过程中还是发现不少问题的,整体的感觉就是产品尚在初级阶段,存在不少不完善不合理的地方。
不支持 html 后缀#
这个问题非常尴尬,真的是不用不知道。具体表现是访问一个以 .html
为后缀的 url 时,会被自动重定向到不含 .html
的地址。例如访问 https://keenwon.com/rem-layout.html
时会自动 308 重定向到 https://keenwon.com/rem-layout
。
也许,也许吧,.html
后缀真的没什么用,Cloudflare 也是这么想的,外加 308 重定向了,目前看对 SEO 的影响不大,但就是非常别扭。而我的网站,正常的 SPA 路由跳转没任何问题,刷新或者直接进入具体页面,就 404 了,用过前端路由的都懂。
目前这个问题我选择忍了,代码也改了。在排查的过程中也发现它的官方文档里写了:
If an HTML file is found with a matching path to the current route requested, Pages will serve it. Pages will also redirect HTML pages to their extension-less counterparts: for instance, /contact.html will be redirected to /contact, and /about/index.html will be redirected to /about/.
官方的社区里也有很多人反馈这个问题,不知道后续会不会解决。