Products
GG网络技术分享 2025-03-18 16:12 0
从 2021 年元旦 Vite 发布 2.0 Beta 版就一直在关注 Vite 的动态,借着春节放假有时间,而且 Vue 3.0 和 Vite 2.0 都才大版本更新上线不久,预感后面会火,先开荒尝试一波,也当给以后工作上的业务先提前踩踩坑,对博客做了第三次重构,这一次把客户端和服务端都重新写了,由 PHP 的 LNMP 全家桶全部换成了前端侧的技术栈。
在经历了春节假期每天大概花 2 ~ 3 小时的投入,终于如期上线,第一个版本是发布于 2 月 14 日情人节 ,算是给自己的情人节礼物,当时是先部署在我闲置的香港服务器做了一波测试服调试,期间做了一些体验上的优化,然后 2 月 18 日 在休假的最后一天,部署到我正式服务器上了。
而且特别巧的是,这一天也是 Vite 2.0 正式版发布的日子:Vite 2.0 发布了 - 尤雨溪[1],同一天上线,就感觉特别美好,值得纪念。
LightHouse 的打分
本次重构后,从开发到部署更新的运作流程图如下,日常只需要维护 GitHub 仓库的代码,其他的都是自动化完成。
博客运作流程
这次重构,并非是因为放假有空就找点事情做,而是带着几个目的来的:
更多的更多,尽在未来,这肯定不是最后的一个版本,还有非常大的优化空间。
其实去年就有想法要对博客做一波改版,但有几个原因导致一拖再拖,一个是因为业务比较忙(这个没办法,工作为重),一个是懒(主要是懒得去思考怎么设计,当然期间有在考虑一些不同的落地方案),还有一个主要的原因是当时 Vue 3.0 刚发布,我当时主要的精力放在踩坑体验 3.0,那段时间,大部分的时间和精力都放在撰写 Vue3.0 学习教程与实战案例[9] 上面去了,休息时间有限,能够闲下来的时间也只有下班回来和周末,除掉一些自己的事情外,留下来捣鼓新东西的时间并不算很多,只能先押后了。
相比 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 ,考虑过 Nuxt[10] 、Vapper[11] 等一些比较流行的开箱即用的 SSR 框架,但这些框架目前都还在弄 Vue 2.0,甚至部分框架看起来有点 “弃坑” 的趋势(背靠字节大厂的 Vapper 居然一年多没更新了 emm…… )。
加上搞 SSR 的话,服务器成本比较高,我的低配 ECS 可能 Hold 不住,好好玩一玩的话还要投点钱,想了想先算了,那么退而求次就是上 SSG 。
玩转 SSG 也是有考虑过一些开箱即用的 SSG 框架,比如用的人最多的 Hexo[12],但我本身一直对 Hexo 不太感兴趣,而且似乎满大街随便找一个独立博客都是基于 Hexo 的,模板也千篇一律,缺乏个人特色。
好友小毅 @chawyehsu[13] 安利的 Saber[14],跑了个 demo 玩了一下,觉得真的蛮不错的,原本打算就直接用 Saber 的,不过目前 Saber 还是以 Vue 2.0 为主(听说下个版本会支持 3.0 ,不过也不知道什么时候会发布),由于内心实在是非常想用 Vue3 ,所以这个方案最终作为备选。
好吧,对 3.0 的执念,还让我想起两个 Vue 官方的作品:VuePress[15]和它的弟弟 VitePress[16],他们的新版本都是基于 Vue 3.0,而且已经可以用了,但一直以来我觉得它们都更适合用来写项目文档……
期间,Vite 官网在 2.0 Beta 版发布后,也新增了一 Part Server-Side Rendering | Vite[17] 指导如何实现 Vite SSR,我觉得可行。
加上有两个开源项目让我非常感兴趣,一个是 vite-ssr[18],一个是 vite-ssg[19],我也分别对他们跑了 demo ,很给力,So,最后决定基于这两个开源项目之一,选择自己搭脚手架……
最终用到的核心技术是:
当然还要考虑的事情很多,每个环节还要用到不同的技术栈,具体我在下面逐个环节说明。
下面来说说决定重构之后,整个思考的过程顺序,以及对每一个技术模块的技术栈选型原因分析吧,希望对有计划重构项目的朋友带来一些帮助。
其实 Vue-CLI[20] 对 Vue 3.0 的支持已经非常好了,我的 Vue 3.0 教程[21] 也是基于 Vue-CLI 写的。
之所以选择 Vite,一方面是它的构建速度真的比 Webpack[22] 要快好多,另一方面是,自从 Vue 3.0 推出以来, Vue 官方团队就一直在投入精力优化和宣传 Vite,尽管 1.0 版本的功能和生态不如人意,但超快的构建速度已经体现了出来。
加上在我准备动手重构的时候官方刚好发布了 2.0 大更新,对比了 1.0 简直是质的飞跃,让我非常感兴趣,而且按照目前官方团队的态度,我觉得后面 Vite 会逐步代替 Vue-CLI ,提前了解,提前踩坑,对以后的工作也有帮助。
而且在生态方面,Vite 2.0 的各种支持都算很完善了,不得不说整个春节期间,Vue 团队的人都在忙着给 Vite 2.0 干活,我在春节提的 Issue,基本上 2 ~ 3 小时就能给我回应,解决问题速度非常快(大过年的耶!),重构过程感觉自己拥有一个强大的技术支持团队一样!
开荒虽然辛苦,但也有另一番乐趣!
这是在选择合适的构建工具之后,应该考虑的第二件事。
个人博客之前一直选择用 WordPress ,一方面除了有 LNMP[23] 一键部署等快速搭建方案,和各种各样的模板之外,主要也是归功于 WP 对 SEO 的支持也是非常好,我这个博客的日常访问都是来自于搜索引擎。
单纯选择用 Vue 3.0 重新开发 SPA 应用肯定会丢失 SEO,所以才有了前面的 技术栈的选择[24],本次是通过 SSG 方案来落地服务端渲染。
在开始动手之前,还要对网站架构做一波规划,盲目动手只能给自己挖坑,自己的博客虽然说内容不多,但也有一些东西要考虑:
当然其他的如移动端适配啥的也要看情况顾及,之前博客还有一个小程序版本,不过因为没人看(害,真的整整一年过去了,完全没人看小程序版本…),所以小程序的依赖保留没有在这次的重构兼容考虑范围里,重构完毕后我就直接把原来的服务停了,回头有空了再重新写一版接口给小程序用。
基于 Vue 3.0 的项目,主要的模板肯定还是 Vue 文件,站点的主要结构、页面的布局、美化等等都是基于 .vue 文件,只需要按照原来的习惯,路由页面放在你的 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 项目的习惯去开发就可以了,如果有一些思路被卡住不知道怎么下手,可以参考我仓库源码。
有设计稿的时候我更喜欢借助 CSS 预处理器(目前常用 Stylus[28]),借助他们的变量 、 嵌套书写,以及 Mixin 、 Extend 等功能,避免写原生 CSS 带来的烦恼。
没有设计稿的时候,会用上 Ant Design[29] 等 UI 框架来帮我减少页面设计上的一些时间浪费,但这些框架通常更适合用在 B 端产品。
去年底在知乎刷到过一篇 如何评价 CSS 框架 TailwindCSS?[30] ,了解到一款全新的 CSS 框架 Tailwind CSS,乍一看很像是在开历史的倒车,回归原子类 className ,评价也是褒贬不一,自己光看文档的时候也是想着这啥玩意…
但是考虑到如果真的是开倒车,凭什么可以拿到 3 万的 Star,抱着试一下的心态在这次重构里面引入尝试,确实真香!
目前感受到的好处就是:
比如,你要实现一个容器内完全居中,手写 CSS 是:
.container{
display:flex;
justify-content:center;
align-items:center;
width:100px;
height:100px;
}
用 Tailwind CSS 的写法是:
<divclass="flexjustify-centeritems-centerw-40h-40"></div>
写法跟你在 VSCode 里自动补全代码时,敲入的命令非常接近,不像传统的 UI 框架一样,你写个标签就自动生成按钮,都不知道它是怎么写出来的(这也是我比较少想用 UI 框架的原因,我怕久了自己都不会写了),实际上,使用 Tailwind 之后,你还是在自己写 CSS, 只不过更方便了!
传统的 Atom CSS ,引入了就得整包引入,而 Tailwind 可以借助 PostCSS ,可以在最终项目构建的时候,抽离出我们用到的样式,用不到的会被直接扔掉。
我自己体验了一下,核心样式文件在配置 Purge 之前构建出来大概有 6M 多,Purge 之后只有 24K !
比如,我要写一个通用的图片样式,让图片具备自适配不变型的效果,我只需要借助 @apply 像这样子:
.img{
@applyw-fullh-fullobject-cover;
}
编译出来就是我想要的效果:
.img{
width:100%;
height:100%;
-o-object-fit:cover;
object-fit:cover;
}
点一下切换皮肤:
借助 PostCSS Language[31] 和 CSS Variable[32],可以轻松的书写像 CSS 预处理一样的嵌套和变量。
a{
color:var(--fg-deeper);
text-decoration:none;
&:hover{
border-bottom:1pxsolidvar(--fg-light);
}
}
独立的文件使用 .postcss 或者 .pcss 作为文件后缀,在 Vue 组件里则使用 <style lang="postcss"></style> 来指定 PostCSS Language 。
当然,说的再多也不如亲手写一写,我之前在知乎也是看了好久始终不能决定用不用,之前赶业务也没时间,这一次也终于动手体验了一把,后悔,特别后悔,后悔怎么没有早点用!!!
虽然前面的 服务端渲染[33] 帮我们解决了空 HTML 文档的问题,但要更好的进行 SEO 优化,还需要落实到具体的页面上去。
比如页面的 title 、 description 、 keyword 等等,这里我是用到了以下两个工具来帮我实现每个页面的 TKD 定制。
gray-matter[34]:支持对 .md 文件的 TKD 优化,你可以在 Markdown 文件的最前面加入这样的代码,即可实现对页面展示对应的 TKD 信息。
---
title:这是页面的标题
desc:这是页面的描述
keywords:关键词1,关键词2,关键词3
---
下面是要书写的Markdown内容…
@vueuse/head[35]:可以让你在 .vue 文件里实现优化,在 Vue 组件里的 script 部分,写入以下的代码,就可以实现 TKD 信息的配置。
import{useHead}from'@vueuse/head'
useHead({
meta:[
{
name:'title',
content:'这是页面的标题'
},
{
name:'description',
content:'这是页面的描述'
},
{
name:'keywords',
content:'关键词1,关键词2,关键词3'
}
]
})
你还可以扩展更多的信息上去,具体都在各自对应的 Github 仓库的 README 里有详细的说明。
当然,SEO 优化远远不止这一点,包括 robots 、 链接语义化 、减少死链 、 旧地址重定向等等,后面也会有说明。
静态资源指 js 、 css 、 img 这些资源,放自己服务器也不是不好,我之前就是放自己服务器上,没有去改,虽然 WordPress 虽然有配置 CDN 的插件,但是 CDN 平台诸如七牛、又拍云,免费额度只针对 http , 都是需要付费才可以使用 https,总的来说还是要多出一笔钱来处理这块服务,反正自己的博客访问量不大,而且技术博客很少多媒体资源,日常使用的带宽消耗很少,我三年前在阿里云充的 50 块钱,三年过去了到现在还有 45.91 …
不过这次改版就不一样了,后续我可能还会开辟一些图片模块,加上改版后是把项目托管到了 Github ,先天优势存在,那么就要多考虑一下利用 Github 提供的免费服务了!
开发过 NPM 包的同学,或者日常使用 NPM 插件比较细心的同学,应该能够发现发布在 NPM 上的包都自动部署到了 CDN 平台,诸如 jsdelivr 、 unpkg 、cdnjs 等等,那么 Github 和这些 CDN 能关联吗?在此之前其实我也没去关注能不能,但这一次我查了一下,确实可以,而且其中对国内访问速度最友好的 jsdelivr ,支持度最高!超棒的!
关于 jsdelivr 的速度可以参考:国内有哪些靠谱的 Javascript 库 CDN 可用?[36],也可以测试下我的博客,我自己对测试结果还是挺满意的。
测试我自己网站的速度
所以最后我是把所有静态资源都指向了 jsdelivr CDN ,它无需你自己再做任何部署工作,只需要把代码文件更新到你的 GitHub 仓库里,就会自动同步到 jsdelivr 。
访问格式为在 jsdelivr CDN 官网[37] 有案例说明,更多用法可以查看官网的文档 Features - jsdelivr[38],为了避免项目源码过大,你可以像我一样单独创建一个类似 assets-storage[39] 这样的仓库用来存储这些静态资源,在仓库的 README 也有简单介绍下如何引用 CDN 地址和清除 CDN 缓存。
回到项目里,只需要在 vite.config.ts[40] 里修改 base 的路径即可。
exportdefaultdefineConfig({
base:isDev
?'/'
:'https://cdn.jsdelivr.net/gh/chengpeiquan/chengpeiquan.com@gh-pages/'
})
详细可以看官网的文档 Configuring Vite | Vite[41]。
当然这种方式如果你用平时的命令行或者老乌龟界面工具来提交文件,始终还是比较麻烦,这里推荐一个现成的图床工具 PicGo[42] ,支持多个平台的 CDN 服务,其中就有 Github 。
PicGo 图床界面
你可以在 Github 仓库上的 Releases[43] 下载最新的客户端版本,只是使用的话,可以单独下载对应系统的安装文件,不需要克隆整个仓库下来自己构建。
本次的资源导出主要是指原来的那些图片,前面有提到,我之前没有启动 CDN 服务,所以图片资源都还在自己的服务器上。
WordPress 的上传资源都存放在 /wp-content/uploads/ 目录下,阿里云非常方便的就是,你可以连 SFTP 上去把这些文件直接拖下来就可以了。
重新传到 Github 上又非常简单,克隆你的仓库下来后,放到指定的文件夹里,重新提交就可以了。
等未来某一次你不想继续用 Github 托管了,只需要把仓库拉下来,所有文件又都在了,都是非常方便和灵活。
这一部分主要针对原来的文章,虽然我之前的 WordPress 就开启了 Markdown 编辑器支持,但如 SEO 优化[44] 里提到的,缺少很多 TKD 信息配置,而且里面的图片地址也都要更换为 CDN 的路径,所以就算用现成工具去处理 HTML / XML 转 Markdown,都还要去补充这些信息,也比较繁琐。
所以是借助了 Node 编写了个静态爬虫,在爬取过程中对一些内容进行追加、转换。
具体的实现可以参考我之前写的 网站改版迁移经验记录:基于 node 的爬虫编写[45] ,这里就不重复赘述了。
既然是 Vue 项目,那么当然支持 Vue 系的统计插件,之前写的两个统计平台插件,都是可以开箱即用的,均已支持 Vue 3.0 的使用。你可以在 main.ts[46] 里了解如何开启流量的统计上报功能,如果你需要记录埋点,也都有 API 可以轻松触发数据的上报。
百度统计:vue-baidu-analytics[47]
友盟统计:vue-cnzz-analytics[48]
服务端之前是 WordPress 所依赖的 Nginx + PHP + MySQL ,这一次重构也把服务端直接换了,更换为 Node.JS + Express ,通过 PM2 守护进程来运行在阿里云。
对,这一次没有数据库,第一版暂时不打算做数据库,暂时用不到,目前大部分数据都已经迁移到 Github 仓库了,下个版本功能迭代用到了再考虑弄一下。
我的服务器系统是 CentOS 7,也就是 Linux 系统,关于 Linux 下如何安装 Node ,搜素引擎很多方法,这里也不赘述了,放几个自己用到的关键命令参考吧。
sudoyumcleanallsudoyummakecachesudoyumupdatesudoyumupgrade-y
sudoyuminstallnpmsudonpminstall-gnsudonstable
npmi-gyarn
yarnglobaladdpm2
其他的步骤就不用说了,创建服务器的文件夹,初始化,安装 express[52] 或者其他你更熟悉的服务程序,搞起吧!
第一版其实不复杂,后面有需要会继续迭代。
代码托管在 GitHub 的好处就是 GitHub Actions 可以帮我们实现 CI / CD,通过配置分支的 push 或者 pull_request 等行为来实现自动触发项目的构建打包,并实现一键部署到阿里云服务器。
具体的脚本可以参考我写的 workflow[53] ,里面都提供了注释。
workflow 里所有以 secrets.XXXXXX 的格式均为仓库独立配置的密钥变量,在仓库的 settings > Actions secrets 里添加。
其中一些关键环节说明如下:
如果其中有什么环节不清楚的,善用搜索引擎,或者到我博客仓库给我提 issue 也可以。
如果你不是托管在 GitHub ,而是别的 Git 平台诸如自建的 Gitlab ,你也可以通过 Jenkins[57] 去配置 CI / CD 的支持。
使用 Vue-CLI 创建新项目的时候,可以了解到有一个选项是关于 PWA 的,关于 PWA 的定义建议直接阅读 渐进式 Web 应用(PWA) | MDN[58] 。
Vite 官方团队也对 PWA 做了支持,通过 vite-plugin-pwa[59] 可以方便的实现一个离线应用的配置。
关于 PWA 的配置可以参考我的项目,这里单独说一下需要特别注意的点:
其他的选项根据实际需要去处理就可以了。
因为网站的设计一向不是我的专长,加上不喜欢花里胡哨的东西,所以这一次重构后的 UI 设计还是基本继承了原来的风格。
但也有一些新的迭代,比如加上了跟随系统的暗黑风格(也可以通过导航右上角进行手动切换),还有首页的变化,对于内容不多的博客来说,挺好的一个 idea,这是来自好友小毅 The Art of Chawye Hsu[62] 和 Vite 开发者 Antfu Anthony Fu[63] 的博客参考。
当然,整个项目的重构,更多的技术支持来自于 Anthony,他也是 Vue 和 Vite 官方团队的开发者,他比我早几天上线的 Rewrite in Vite[64] 给了我很多思路,很多基于 Vite 的插件也是他写的,都是在这几天发布和迭代,有那种瞌睡来了枕头的感觉,美妙!
完整的项目依赖和配置请查看仓库的 package.json[65] 和 vite.config.ts[66] ,整个项目也完全开源了,具体的实现可以查看 Github 仓库[67] ,在这里就不赘述了,如果觉得对你有用,欢迎 Star 。
今天给大家分享让wordpress企业网站搜索出来的结果页高亮显示的实现方法。
首页需要在网站的主题函数function.php中加入下面代码:
functionhls_set_query(){$query=attribute_escape(get_search_query());
if(strlen($query)>0){
echo'
<scripttype="text/javascript">
varhls_query="'.$query.'";
</script>
';
}
}
functionhls_init_jquery(){
wp_enqueue_script('jquery');
}
add_action('init','hls_init_jquery');
add_action('wp_print_scripts','hls_set_query');
然后把样式代码引入搜索页面中
<styletype="text/css"media="screen">.hls{background:#D3E18A;}
</style>
<scripttype="text/javascript">
jQuery.fn.extend({
highlight:function(search,insensitive,hls_class){
varregex=newRegExp("(<[^>]*>)|(b"+search.replace(/([-.*+?^${}()|[]/])/g,"$1")+")",insensitive?"ig":"g");
returnthis.html(this.html().replace(regex,function(a,b,c){
return(a.charAt(0)=="<")?a:"<strongclass=""+hls_class+"">"+c+"</strong>";
}));
}
});
jQuery(document).ready(function($){
if(typeof(hls_query)!='undefined'){
$("#post-area").highlight(hls_query,1,"hls");
}
});
</script>
完成后,就可以显示搜索高亮了。
Demand feedback