前段时间写了一篇vuepress2的开发文章,很多前端小伙伴看,给了我很多鼓励,写这个的原因是我们的百家饭OpenAPI平台是用vuepress搭建的,最开始选型是因为开始的时候觉得只是一个介绍性的产品网站,所以选型用了类似vue的vuepress,但是随着百家饭站点开发的深入,vuepress的很多问题给我们造成了很多的麻烦,以至于我们目前的架构变成了这样一个复杂结构:
|---/api/home (工作台页面,vue开发)
|---/page/{id} 富格式评论页面,lit开发,后端做服务器渲染
|---其他页面,vuepress开发
可以看到,除了原有的一些静态内容页面之外,我们原本使用vuepress开发的工作台页面被移出来,使用vue做了SPA,并和其他页面使用链接进行跳转。
![](https://i-blog.csdnimg.cn/blog_migrate/803f47b115398b590d9929d7951ddb93.png)
而评论页面(类似blog页面)也被拿出来单独使用lit进行了开发。
![](https://i-blog.csdnimg.cn/blog_migrate/08d3d2334e5c7c40183677a07d964c4c.png)
这样做的原因有哪些呢?
vuepress严重的ssr问题
vuepress使用ssr来将md文件、模板文件统一编译成html文件,实现了将md文件作为html文件的目的,这种编译过程实际上是利用了ssr来完成的,md编译过程就是一个ssr编译的过程,造成了几个常见的问题。
编译不成功
经常性的会出现因element-plus或其他插件不支持ssr导致的编译不成功问题。
Object.remove undefined问题
如果顺利的通过了编译,也有可能在运行期出现一些莫名其妙的Object.remove时的undefined问题,这些问题通常是和vuepress重新绘制页面时出现的问题有关,使得解决问题十分麻烦,更要命的是这种问题只出现在编译后的实际运行阶段,也就意味着你通常只能在线上的测试或者生产环境遇到这个问题,隐藏很深。
出现这个问题,最直观的后果就是页面混乱。部分组件因绘制出错导致位置或显示错误,还有更麻烦的情况,就是这种情况一旦发生,因为vuepress劫持了浏览器的history进行类vuerouter的动态刷新,使得这种错误无法使用刷新页面进行重置,必须要手动跳转到其他页面再刷新才能完成修正,这样这种问题无法被普通用户解决,可以说一旦出现问题就是致命问题。
在之前的版本中,我们通常会尝试性地将部分组件通过<ClientOnly>包裹地方式解决这个问题,但是最近的更新因调整了整体风格,整体修改量偏大,过程中没有及时做编译预览,出现问题之后已经无法通过回溯来进行错误定位。
最终导致我们不得不在这个页面中放弃使用vuepress。
hydration mismatch问题
vuepress使用ssr其实是在编译前阶段,所以vuepress的ssr其实只能算ssg(server side generation),其生成结果不能修改,否则在实际运行时,就会出hydration mismismatch问题,因为这个问题,导致无法和实际后台服务器配合做动态内容渲染。在做blog页面时,我们尝试了很多种解决方案,都无法绕开这个问题,后来在这个页面选择使用了lit重写,这也是为什么最近我们开了lit教学文章的原因。
lit的好处是他重复使用了最新版本浏览器的shallow dom功能和web component功能,没有使用vdom,动态部分都在js里,而html部分没有特殊的格式要求,那我就可以利用后台模板技术,将html部分进行动态内容替换,而再结合js去做进一步的客户端功能增强。
<body>
<el-header></el-header>
<blog-panel userName="{{ .Message.Username }}" authorIcon="{{.UserIcon}}" id="{{.Message.Id}}"
created="{{ .Message.CreatedAt }}" apiId="{{ .Source.Id}}" userId="{{.Message.UserId}}"
subject="{{.Message.Subject}}">
<div slot="content">
{{ .Message.Content | raw }}</div>
<div slot="api-desc">{{.Source.Description | raw}}</div>
<span slot="api-name">{{.Source.Name}}</span>
</blog-panel>
</body>
这篇文章也是通过总结我们最后的网站架构,给希望使用vuepress的小伙伴做个功能选型参考:
- 当网站功能主要是内容导向的时候,可以使用vuepress做主体框架
- 在部分功能较强的页面,不建议在vuepress中使用太重的第三方插件做深入研发,直接考虑vue做spa会避免很多的开发中的坑。
- 当需要做动态内容渲染的时候,按以下原则做选择,
- 如果不需要考虑搜索引擎优化,直接使用json获取数据做渲染是一个方案
- 如果需要,可能必须要使用其他的框架,vuepress是无法支持的。
- 多项目文件最后通过url路径做跳转即可,相互之间不影响