重构于 Vite:我如何做 SSG静态资源发布以及自动化部署

Posted 前端技术优选

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重构于 Vite:我如何做 SSG静态资源发布以及自动化部署相关的知识,希望对你有一定的参考价值。

运作流程

本次重构后,从开发到部署更新的运作流程图如下,日常只需要维护 GitHub 仓库的代码,其他的都是自动化完成。

博客运作流程
重构的价值

这次重构,并非是因为放假有空就找点事情做,而是带着几个目的来的:

  1. 提前开荒 ,为公司后续的业务提前踩坑,可以为团队进行技术选型提供帮助,因为之前我在做 JSSDK、Vue Plugin 的时候,已经开始脱离 Webpack,用 作为构建工具,而 Vite 正是基于 Rollup ,不仅构建速度非常快,而且也像 Webpack 一样提供了热更新,对于一线开发来说,体验上是非常好的,而且它还是 Vue 团队大力推广的新工具,这让我很有兴趣去研究它。

  2. 了解一下当前的一些新生的前端工具,比如 UI 框架方面之前一直停留在适合 B 端产品的 Ant-Design、 Vuetify 、 饿了么等等,说实话我做 B 端产品的时候才会用,面向 C 端因为有设计稿,我基本上都是手写样式,听闻新一代的 UI 框架 已经有一段时间了,虽然很奇怪为什么还会回到十年前一样用原子类的 class,“开倒车” 竟然还有 3 万多的 Star,让我非常的好奇到底为什么,结果一用,真香!没错,这次博客的样式,就是用的 Tailwind 。还有像 CSS 预处理器之前也一直停留在 Sass / Less / Stylus 三驾马车,这一次我抛弃了他们,用上了 + (因为 WordPress 的高亮插件就是用这个……),这一次我是用了 ,更小巧,颗粒度更细,虽然目前还没有太多时间去定制代码高亮的配色,不过后面有时间想要处理,prism 会更加方便。

  3. 享受从 0 到 1 搭建脚手架的一个过程,目前这个版本算是实现一个简易版的 VuePress ,但是如果一直使用开箱即用的 VuePress ,很多时候并没有想去了解那些功能是怎么实现的,或者用哪些工具可以实现想要的功能(Btw: 我自从用了 Vue-CLI 之后就很久没自己配置 Webpack 了,直到 Rollup 的时候才算重新玩转了一次,这一次的 Vite 又是新的体验)

更多的更多,尽在未来,这肯定不是最后的一个版本,还有非常大的优化空间。

重构前的目标

其实去年就有想法要对博客做一波改版,但有几个原因导致一拖再拖,一个是因为业务比较忙(这个没办法,工作为重),一个是懒(主要是懒得去思考怎么设计,当然期间有在考虑一些不同的落地方案),还有一个主要的原因是当时 Vue 3.0 刚发布,我当时主要的精力放在踩坑体验 3.0,那段时间,大部分的时间和精力都放在撰写 上面去了,休息时间有限,能够闲下来的时间也只有下班回来和周末,除掉一些自己的事情外,留下来捣鼓新东西的时间并不算很多,只能先押后了。

相比 2018 年那次改版,当时只是单纯想重新弄一个干净的博客写东西,这一次的目标是比较明确了,就是从基于 php 的 WordPress,用前端的技术栈全部重构一遍,做一个纯前端的博客出来,当然还要保留 SEO ,就要求还要上 SSR(Server Side Render) 或者 SSG(Server Side Generation) 。

技术栈的选择

由于开工前已经是 2021 年了,因为有前面几个月玩 Vue 3.0 的基础打底,非常想用 3.0 来重构博客,加上元旦期间 Vite 2.0 Beta 版刚好发布(就很突然),注意力完全放在了 Vue3 和 Vite2 上面,非常想跑一下两者结合有多爽。

由于重构的最终目标还是要保持网站的 SEO 能力,所以肯定不能使用默认的 SPA 应用模式,要走服务端渲染,所以技术栈方面只需要考虑两条线:

基于 SSR等一些比较流行的开箱即用的 SSR 框架,但这些框架目前都还在弄 Vue 2.0,甚至部分框架看起来有点 “弃坑” 的趋势(背靠字节大厂的 Vapper 居然一年多没更新了 emm…… )。

加上搞 SSR 的话,服务器成本比较高,我的低配 ECS 可能 Hold 不住,好好玩一玩的话还要投点钱,想了想先算了,那么退而求次就是上 SSG 。

基于 SSG安利的 和它的弟弟 最终敲定指导如何实现 Vite SSR,我觉得可行。

加上有两个开源项目让我非常感兴趣,一个是 重构过程分析

下面来说说决定重构之后,整个思考的过程顺序,以及对每一个技术模块的技术栈选型原因分析吧,希望对有计划重构项目的朋友带来一些帮助。

构建工具对 Vue 3.0 的支持已经非常好了,我的 也是基于 Vue-CLI 写的。

之所以选择 Vite,一方面是它的构建速度真的比 要快好多,另一方面是,自从 Vue 3.0 推出以来, Vue 官方团队就一直在投入精力优化和宣传 Vite,尽管 1.0 版本的功能和生态不如人意,但超快的构建速度已经体现了出来。

加上在我准备动手重构的时候官方刚好发布了 2.0 大更新,对比了 1.0 简直是质的飞跃,让我非常感兴趣,而且按照目前官方团队的态度,我觉得后面 Vite 会逐步代替 Vue-CLI ,提前了解,提前踩坑,对以后的工作也有帮助。

而且在生态方面,Vite 2.0 的各种支持都算很完善了,不得不说整个春节期间,Vue 团队的人都在忙着给 Vite 2.0 干活,我在春节提的 Issue,基本上 2 ~ 3 小时就能给我回应,解决问题速度非常快(大过年的耶!),重构过程感觉自己拥有一个强大的技术支持团队一样!

开荒虽然辛苦,但也有另一番乐趣!

服务端渲染一键部署等快速搭建方案,和各种各样的模板之外,主要也是归功于 WP 对 SEO 的支持也是非常好,我这个博客的日常访问都是来自于搜索引擎。

单纯选择用 Vue 3.0 重新开发 SPA 应用肯定会丢失 SEO,所以才有了前面的 项目架构规划模板开发文件,只需要按照原来的习惯,路由页面放在你的 src/views 文件夹下,组件模板放置于 src/components 下,就可以自动生成路由访问。

同时也加入了 .md 文件的支持,用于书写 Markdown 格式的内容,日常记录博客会更方便,并且像 VuePress 那样,同时支持在 Markdown 里嵌套 Vue,让博客的定制更加灵活。

整个项目的路由页面、组件结构,跟你平时开发 Vue 项目是完全一样的,无缝切换。

src 
├─components 
│ ├─Footer.vue 
│ └─Header.vue 
└─views 
│ ├─[page].vue
├─article 
│ └─rewrite-in-vite.md 
│ ├─about.md 
└─index.vue

在这里推荐几个非常方便的 Vite 插件:

:能够自动读取指定目录下的 Vue / Md 文件生成 Vue 路由,只需要管理好 views 文件夹的层级关系,无需再单独维护路由配置

:一个能让 Markdown 文件像 Vue 组件一样导入使用的插件,它也基于 markdown-it,支持进行一系列 md 生态扩展

样式处理器等 UI 框架来帮我减少页面设计上的一些时间浪费,但这些框架通常更适合用在 B 端产品。

去年底在知乎刷到过一篇 ,了解到一款全新的 CSS 框架 Tailwind CSS,乍一看很像是在开历史的倒车,回归原子类 className ,评价也是褒贬不一,自己光看文档的时候也是想着这啥玩意…

但是考虑到如果真的是开倒车,凭什么可以拿到 3 万的 Star,抱着试一下的心态在这次重构里面引入尝试,确实真香!

目前感受到的好处就是:

延续 CSS 的属性命名,你需要什么属性自己放,也就是自己必须有一定的 CSS 基础,特别是在多端适配方面,不用担心框架用久了自己不会写 CSS 的问题

比如,你要实现一个容器内完全居中,手写 CSS 是:

的前缀就可以轻松定制两款皮肤

点一下切换皮肤:

用了 Tailwind 之后,你几乎可以不用写 Sass / Stylus 了,那么问题来了:如何弥补 CSS 预处理器提供的一些功能?

借助 或者 .pcss 作为文件后缀,在 Vue 组件里则使用 <style lang="postcss"></style> 来指定 PostCSS Language 。

当然,说的再多也不如亲手写一写,我之前在知乎也是看了好久始终不能决定用不用,之前赶业务也没时间,这一次也终于动手体验了一把,后悔,特别后悔,后悔怎么没有早点用!!!

SEO 优化帮我们解决了空 html 文档的问题,但要更好的进行 SEO 优化,还需要落实到具体的页面上去。

比如页面的 titledescriptionkeyword 等等,这里我是用到了以下两个工具来帮我实现每个页面的 TKD 定制。

文件的 TKD 优化,你可以在 Markdown 文件的最前面加入这样的代码,即可实现对页面展示对应的 TKD 信息。

---
title: 这是页面的标题
desc: 这是页面的描述
keywords: 关键词1,关键词2,关键词3
---

下面是要书写的 Markdown 内容…

文件里实现优化,在 Vue 组件里的 script 部分,写入以下的代码,就可以实现 TKD 信息的配置。

静态资源处理有案例说明,更多用法可以查看官网的文档 这样的仓库用来存储这些静态资源,在仓库的 README 也有简单介绍下如何引用 CDN 地址和清除 CDN 缓存。

回到项目里,只需要在 里修改 base 的路径即可。

,支持多个平台的 CDN 服务,其中就有 Github 。

PicGo 图床界面

你可以在 Github 仓库上的 下载最新的客户端版本,只是使用的话,可以单独下载对应系统的安装文件,不需要克隆整个仓库下来自己构建。

资源导出目录下,阿里云非常方便的就是,你可以连 SFTP 上去把这些文件直接拖下来就可以了。

重新传到 Github 上又非常简单,克隆你的仓库下来后,放到指定的文件夹里,重新提交就可以了。

等未来某一次你不想继续用 Github 托管了,只需要把仓库拉下来,所有文件又都在了,都是非常方便和灵活。

爬虫编写里提到的,缺少很多 TKD 信息配置,而且里面的图片地址也都要更换为 CDN 的路径,所以就算用现成工具去处理 HTML / XML 转 Markdown,都还要去补充这些信息,也比较繁琐。

所以是借助了 Node 编写了个静态爬虫,在爬取过程中对一些内容进行追加、转换。

具体的实现可以参考我之前写的 ,这里就不重复赘述了。

数据统计里了解如何开启流量的统计上报功能,如果你需要记录埋点,也都有 API 可以轻松触发数据的上报。

百度统计:服务端开发,没错,我现在更喜欢用 yarn 来进行包管理,这一步你可以跳过

npm i -g yarn
  1. 然后是全局安装
yarn global add pm2

其他的步骤就不用说了,创建服务器的文件夹,初始化,安装 或者其他你更熟悉的服务程序,搞起吧!

有几件事要特别叮嘱一下:

1. 因为服务端变了,如果原来有开启 HTTPS,记得重新配置你的 SSL 证书(我用的是阿里云的免费证书,只需要 1 年更换 1 次)

2. 域名也要重新做 301 重定向(HTTP 强切 HTTPS , WWW 强切无 3W 等)

3. 检查之前是否有在推广的的链接挂掉了,也要重新 301 到新地址 (比如 RSS 源之前是 /feed/ ,现在是 /feed.xml)

4. 最重要的,配置上对路由 history 模式的支持

第一版其实不复杂,后面有需要会继续迭代。

自动化部署,里面都提供了注释。

workflow 里所有以 secrets.XXXXXX 的格式均为仓库独立配置的密钥变量,在仓库的 settings > Actions secrets 里添加。

其中一些关键环节说明如下:

  1. on 是指分支行为,我配置了合并分支才会触发,因为平时都是托管在 develop 分支,包括未开发完毕的功能,写一半的文章草稿,只有确认可以发布的代码,才会合并到 main 进行更新

  2. jobs 是触发自动打包 / 发布一系列行为的各种操作,从上到下按顺序处理,其中的 ACCESS_TOKEN 是 GitHub 的 Token,请来 创建,创建后只会显示一次,请保存好,后面涉及到 Token 的地方可以重复使用同一个 Token,请勿泄露!

  3. gh-pages 分支是打包完毕后的文件,推送到阿里云服务器的也是这个分支下的所有文件,之所以托管一份在 GitHub,是因为我们前面部署了 CDN 支持,JS / CSS 文件是需要读取这个分支的 CDN 文件

  4. 部署到阿里云的环节,配置的 SERVER_SSH_KEY 是自己服务器的密钥对,如果你也是跟我一样使用阿里云的 ECS ,可以参考 是自己服务器的公网 IP,这个其实可以不用配置为密钥变量,因为 ping 一下你的域名也知道是什么 IP ,只是因为我有两台服务器,所以配置为变量可以方便的通过 SERVER_IPSERVER_IP_TEST 去切换,其他变量其实也有一个 TEST 版本

  5. 最后的 TARGET 是你在服务器上,node 服务器所安装的目录。

如果其中有什么环节不清楚的,善用搜索引擎,或者到我博客仓库给我提 issue 也可以。

如果你不是托管在 GitHub ,而是别的 Git 平台诸如自建的 Gitlab ,你也可以通过 去配置 CI / CD 的支持。

离线应用构建

Vite 官方团队也对 PWA 做了支持,通过 可以方便的实现一个离线应用的配置。

base 选项设置为 CDN 地址时,构建出来的 PWA manifest 资源路径会读取错误,原因是 manifest 不能走 CDN,要单独从网站内读取,虽然跟作者提了优化建议(详见 这个去用,不过最好还是留意原版的更新,这个私有包不会长期维护。

2021-02-22 更新:目前原版已更新,Fix 了我反馈的问题,请使用 v0.5.3 以后的版本可以避免该问题的产生,给作者点赞!

关于 PWA 的配置可以参考我的项目,这里单独说一下需要特别注意的点:

  1. 因为使用了 CDN,所以 scopemanifest.start_url 选项需要显式指定,否则资源会读取出错

  2. 基于我上面提到的路径问题,从 v0.5.3 开始,配置 CDN 的同时,也需要显式指定 base 选项,避免出现 404

其他的选项根据实际需要去处理就可以了。

结语

因为网站的设计一向不是我的专长,加上不喜欢花里胡哨的东西,所以这一次重构后的 UI 设计还是基本继承了原来的风格。

但也有一些新的迭代,比如加上了跟随系统的暗黑风格(也可以通过导航右上角进行手动切换),还有首页的变化,对于内容不多的博客来说,挺好的一个 idea,这是来自好友小毅 和 Vite 开发者 Antfu 的博客参考。

当然,整个项目的重构,更多的技术支持来自于 Anthony,他也是 Vue 和 Vite 官方团队的开发者,他比我早几天上线的 给了我很多思路,很多基于 Vite 的插件也是他写的,都是在这几天发布和迭代,有那种瞌睡来了枕头的感觉,美妙!

完整的项目依赖和配置请查看仓库的  ,整个项目也完全开源了,具体的实现可以查看 ,在这里就不赘述了,如果觉得对你有用,欢迎 Star 。

参考资料
[1]

Vite 2.0 发布了 \\ 尤雨溪: https://zhuanlan.zhihu.com/p/351147547

[2]

Vite 2.0: https://github.com/vitejs/vite

[3]

Rollup: https://github.com/rollup/rollup

[4]

Tailwind CSS: https://github.com/tailwindlabs/tailwindcss

[5]

PostCSS Language: https://github.com/postcss/postcss

[6]

CSS Variable: https://developer.mozilla.org/zh-CN/docs/Web/CSS/--*

[7]

highlight.js: https://github.com/highlightjs/highlight.js

[8]

prism: https://github.com/PrismJS/prism

[9]

Vue3.0 学习教程与实战案例: https://vue3.chengpeiquan.com/

[10]

Nuxt: https://github.com/nuxt/nuxt.js

[11]

Vapper: https://github.com/shuidi-fed/vapper

[12]

Hexo: https://github.com/hexojs/hexo

[13]

@chawyehsu: https://github.com/chawyehsu

[14]

Saber: https://github.com/saberland/saber

[15]

VuePress: https://github.com/vuejs/vuepress

[16]

VitePress: https://github.com/vuejs/vitepress

[17]

Server-Side Rendering | Vite: https://vitejs.dev/guide/ssr.html

[18]

vite-ssr: https://github.com/frandiox/vite-ssr

[19]

vite-ssg: https://github.com/antfu/vite-ssg

[20]

Vue-CLI: https://github.com/vuejs/vue-cli

[21]

Vue 3.0 教程: https://vue3.chengpeiquan.com/

[22]

Webpack: https://github.com/webpack/webpack

[23]

LNMP: https://github.com/licess/lnmp

[24]

技术栈的选择: #%E6%8A%80%E6%9C%AF%E6%A0%88%E7%9A%84%E9%80%89%E6%8B%A9

[25]

vite-plugin-pages: https://github.com/hannoeru/vite-plugin-pages

[26]

vite-plugin-md: https://github.com/antfu/vite-plugin-md

[27]

vite-plugin-components: https://github.com/antfu/vite-plugin-components

[28]

Stylus: https://github.com/stylus/stylus

[29]

Ant Design: https://github.com/vueComponent/ant-design-vue

[30]

如何评价 CSS 框架 TailwindCSS?: https://www.zhihu.com/question/337939566

[31]

PostCSS Language: https://github.com/postcss/postcss

[32]

CSS Variable: https://developer.mozilla.org/zh-CN/docs/Web/CSS/--*

[33]

服务端渲染: #%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93

[34]

gray-matter: https://github.com/jonschlinkert/gray-matter

[35]

@vueuse/head: https://github.com/vueuse/head

[36]

国内有哪些靠谱的 javascript 库 CDN 可用?: https://www.zhihu.com/question/20227463/answer/370662453

[37]

jsdelivr CDN 官网: https://www.jsdelivr.com/?docs=gh

[38]

Features - jsdelivr: https://www.jsdelivr.com/features#gh

[39]

assets-storage: https://github.com/chengpeiquan/assets-storage

[40]

vite.config.ts: https://github.com/chengpeiquan/chengpeiquan.com/blob/main/vite.config.ts

[41]

Configuring Vite | Vite: https://vitejs.dev/config/#base

[42]

PicGo: https://github.com/Molunerfinn/PicGo

[43]

Releases: https://github.com/Molunerfinn/PicGo/releases

[44]

SEO 优化: #seo-%E4%BC%98%E5%8C%96

[45]

网站改版迁移经验记录:基于 node 的爬虫编写: https://chengpeiquan.com/article/node-web-crawler

[46]

main.ts: https://github.com/chengpeiquan/chengpeiquan.com/blob/main/src/main.ts

[47]

vue-baidu-analytics: https://github.com/chengpeiquan/vue-baidu-analytics

[48]

vue-cnzz-analytics: https://github.com/chengpeiquan/vue-cnzz-analytics

[49]

yarn: https://github.com/yarnpkg/yarn

[50]

pm2: https://github.com/Unitech/pm2

[51]

forever: https://github.com/foreversd/forever

[52]

express: https://github.com/expressjs/express

[53]

workflow: https://github.com/chengpeiquan/chengpeiquan.com/blob/main/.github/workflows/github-ci.yml

[54]

Personal access tokens: https://github.com/settings/tokens

[55]

创建 SSH 密钥对: https://www.alibabacloud.com/help/zh/doc-detail/51793.htm

[56]

绑定 SSH 密钥对: https://www.alibabacloud.com/help/zh/doc-detail/51796.htm

[57]

Jenkins: https://github.com/jenkinsci/jenkins

[58]

渐进式 Web 应用(PWA) | MDN: https://developer.mozilla.org/zh-CN/docs/Web/Progressive_web_apps

[59]

vite-plugin-pwa: https://github.com/antfu/vite-plugin-pwa

[60]

#25: https://github.com/antfu/vite-plugin-pwa/pull/25

[61]

@chengpeiquan/vite-plugin-pwa: https://www.npmjs.com/package/@chengpeiquan/vite-plugin-pwa

[62]

The Art of Chawye Hsu: https://chawyehsu.com/

[63]

Anthony Fu: https://antfu.me/

[64]

Rewrite in Vite: https://antfu.me/posts/rewrite-in-vite

[65]

package.json: https://github.com/chengpeiquan/chengpeiquan.com/blob/main/package.json

[66]

vite.config.ts: https://github.com/chengpeiquan/chengpeiquan.com/blob/main/vite.config.ts

[67]

Github 仓库: https://github.com/chengpeiquan/chengpeiquan.com


在看点这里

NextJS 静态 SSG 认证

【中文标题】NextJS 静态 SSG 认证【英文标题】:NextJS static SSG authentication 【发布时间】:2021-08-11 05:03:37 【问题描述】:

用例

我正在创建一个付费博客网站,人们可以在该网站上向博主付费以查看他们的博客。

我选择的解决方案

我选择了 NextJS 来构建静态内容(SSG)。使用后备选项,静态内容也可以在站点部署后构建。

问题

现在,问题是身份验证。我们无法验证服务器上的任何传入请求,例如 s-s-r

检查身份验证的唯一方法是在客户端。使用useEffect钩子检查当前用户是否经过身份验证。

但是,这种方法的问题在于,任何用户都可以在客户端禁用javaScript 来查看内容。

有没有办法在服务器端验证 SSG 页面请求。

我不想使用 s-s-r,因为会增加成本。

【问题讨论】:

【参考方案1】:

您可以使用名为 Auth0 的服务来实现静态站点身份验证。它每月最多免费提供数千个请求,并且具有您可以使用的 React 组件。确保遵循 auth0-react 而不是 nextjs-auth0 的教程(这是针对 s-s-r)。

这里是 Auth0 的链接:https://auth0.com/

【讨论】:

【参考方案2】:

如果用户在 SSG 上进行身份验证,您可以返回 null。如果您不通过 API 加载任何内容,那么用户将能够在代码中看到它(但没有多少用户会这样做)。如果您还没有设法解决此问题,现在可以选择 Vercel Edge Functions。

【讨论】:

以上是关于重构于 Vite:我如何做 SSG静态资源发布以及自动化部署的主要内容,如果未能解决你的问题,请参考以下文章

NextJS 静态 SSG 认证

SSG和s-s-r如何选择?

Vite中不能使用require,该怎么动态获取静态图片资源?

vite打包配置(静态资源合并打包/清除log/gzip压缩/ENV配置等)

在 Vite 中创建 api 调用(使用 ViteSSE / ViteSSE)

(ssg-wsg) 如何在 SSG-WSG API 中使用 PHP 中的初始化向量进行 AES 加密

(c)2006-2024 SYSTEM All Rights Reserved IT常识