前情提要
在《<font style=color:rgb(18, 18, 18);>【已被采纳】基本功不好,如何做开源贡献?使用 ChatGPT 写代码实录。 - Jeff Tian的文章 - 知乎 》中提到,我使用 vitepress 打造了一个完美的写作平台。其中有一个不能嵌套包含的问题,也利用 ChatGPT 解决了,该贡献最终在 vitepress 1.0.0-beta.6 的发布中带上去了。
<font style=color:rgb(18, 18, 18);>虽然可以在一屏中展示书籍的所有内容,但是展示的形式仍然不完美,即和真正的纸书呈现形式相差太大。调研了 pagedjs、pandoc、vitepress-export-pdf、vivliostyle.js<font style=color:rgb(18, 18, 18);> 等等,发现各自有各自的优势,结合自己的使用场景是在浏览器上拥有纸质书籍的阅读体验,同时希望拥有最少的代码侵入,最终决定还是使用 pagedjs 来在浏览器进行书籍页面渲染。
<font style=color:rgb(18, 18, 18);>惊艳的效果
通过 pagedjs 的官网指引,在 vitepress 里引入了它,并加上了一些额外的 css 样式后,在开发模式下,完美渲染!
引入的方式是在 docs.vitepressconfig.ts文件中的 head 区增加如下内容:
typescript export default withMermaid( defineConfig({ head: [ [ script, { type: text/javascript, async: true, defer: true, src: https://unpkg.com/pagedjs/dist/paged.polyfill.js } ], ] }) )
然后,在 main.md 文件中增加相应的 style:
markdown
注意以上的 @page 指令,它将书籍页面左右展示,并在页眉和页脚中增加一个额外的文本,yarn docs:dev 执行后的效果如下:
奇怪的 BUG
然而,奇怪的是,一旦发布上线,以上效果全没了…… 只剩下了 pagedjs 将页面分割成多页展示,却没有页眉页脚了。
分析
看起来,vitepress 在本地开发模式下是启动了一个 Web 服务器来托管整个站点,但是一旦打包成静态页面文件,这个打包过程中会做一些事情,破坏了 pagedjs 的工作流。
说实话,我只想无脑使用这个工具,比如 vitepress 也好、pagedjs 也好,我能用就行,至于它们是怎么设计的,原理是什么,我没有兴趣知道。
然而现实是,我一用就发现不好用,有可能是姿势不对,但不去了解原理,就无法得知到底哪里不对,因为并没有现成的文档。vitepress 文档写得很好,然而没有也不应该专门为 pagedjs 的集成写相关的文档;对 pagedjs 来说也是如此,它已经有很完善的文档了,但却没有也不应该专门为在 vitepress 中的使用写相关的文档。
一般我是不建议阅读所谓框架或者库的源码的,毕竟只要会使用就可以了。但在使用过程中发现了问题,不得不去读一点源码。在开始阅读源码之前,我做了一些分析。
因为在开发者服务器运行时,一切正常。而打包完成后,不工作了。所以这很可能是由于打包过程中破坏(重建)了某些文件结构,导致最终 pagedjs 运行时找不到相关的文件。
排查
顺着这个思路,我对比了一下 vitepress 开发者服务器运行时渲染的 html 和打包完成后的 html,发现在开发者服务器运行时下,html 中的 css 和 script 基本上和自己在 markdown 文件中引入的非常接近,而打包后则属于是面目全非,特别是 css 和 scripts 全部被重新命名并且以一种特别的方式引入。就连在 markdown 文件中内联的 css 样式,都被打包到独立文件中去了。
所以我怀疑 pagedjs 没有办法找到相关的样式文件,导致了最终渲染出来的内容缺失(通过 page 指令渲染的内容全没了)。
于是我去看了一下 pagedjs 的源码,了解到 preview 函数接收 3 个参数,其中第 2 个果然是接收一个 css 文件。
又通过其文档看到 css 规则的确是会被解析并最终应用在页眉页脚等地。
实验
之前使用的是引入 CDN 的 polyfill 文件,该文件自动完成所有的工作。现在,我需要使用调用 preview 函数的方式引入 pagedjs,从而为后面调参打好基础。于是删除 docs.vitepressconfig.ts 文件中的 head 部分。
diff export default withMermaid( defineConfig({ head: [
-
[
-
script,
-
{
-
type: text/javascript,
-
async: true,
-
defer: true,
-
src: https://unpkg.com/pagedjs/dist/paged.polyfill.js
-
}
-
})], ]
)
然后将 pagedjs 安装到 node_modules 里:
shell yarn add pagedjs
接着直接在 markdown 文件里添加
markdown
验证了在开发模式工作正常,在打包静态化后重现了之前的问题。
调参
以上实验证明了使用 Previewer 和直接从 CDN 引入 polyfill 是一样的。不过,Previewer 允许自定义参数,现在是默认的。
我将 markdown 内联的样式重新放在一个文件里,为了在编译打包后仍然能引用它,我将它放在了 public 目录下。
由于 css 文件是第二个参数,为了不改动第一个参数和第三个参数,我将它们置为 undefined:
diff
问题解决
到此问题已经解决!完整源代码见: https://github.com/Jeff-Tian/AllAboutIdentity