前情提要

在《<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 执行后的效果如下:

1690781125588 c60796ad c792 476d 8be6 12335e7433af

奇怪的 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 文件。

1690973410656 f8324c11 a861 4f50 b167 5c5add694d42

又通过其文档看到 css 规则的确是会被解析并最终应用在页眉页脚等地。

1690973637836 693af133 c462 468d aaa1 db8a3d583c8d

实验

之前使用的是引入 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 目录下。

1690974002187 13e8bb82 7fd1 4398 97dc eddb66be6c6c

由于 css 文件是第二个参数,为了不改动第一个参数和第三个参数,我将它们置为 undefined:

diff

问题解决

到此问题已经解决!完整源代码见: https://github.com/Jeff-Tian/AllAboutIdentity

在线体验链接: https://identity.jefftian.dev/main.html

1690978001787 8e415eee 209e 4e4f 9404 40adacebf879