# VuePress 集成第三方评论模块

VuePress (opens new window) 是一个 Vue 驱动的静态网站生成器,用来写文档的体验很好,本站就是基于 VuePress 的。

VuePress 官方正在开发针对博客的优化功能Blog Support roadmap (opens new window),已经有人在喊建议集成 disqus(ps:disqus 已经被墙)了,有兴趣的同学可以去投个票。

在官方之前,大家也可以参考本文为自己的博客/文档添加评论模块。

本文采用Gitalk作为示例,效果看文章底部。如果想集成其它第三方模块,本文代码也有一定参考性。
注意:Gitalk 要求用户登录 github 才能评论

# 注册 OAuth application

参考gitalk (opens new window),本博客下的评论区即是 gitalk

你会得到一个 client ID 和一个 client secret,这个将被用于之后的用户登录。

# 创建或准备一个 github 仓库存储评论

Gitalk 将评论都存储在仓库 issue 中,同时要求用户登录 github 才能评论,所以需要先准备一个仓库。 本博客托管在 Github Pages 上,所以直接使用hughfenghen.github.io 仓库 (opens new window)来存储评论了。

# 创建一个enhanceApp.js文件

./vuepress目录下创建enhanceApp.js文件, copy 以下代码到文件中,填写代码中的xxx部分。 如果已存在enhanceApp文件,则 copy try...catch代码块和integrateGitalk函数

// 重试
function tryRun(fn, times = 3) {
  let execCount = 1;

  fn(next);

  function next(delay) {
    if (execCount >= times) return;
    setTimeout(() => {
      execCount += 1;
      fn(next);
    }, delay);
  }
}

function integrateGitalk(router) {
  const linkGitalk = document.createElement('link');
  linkGitalk.href = 'https://unpkg.com/gitalk@1/dist/gitalk.css';
  linkGitalk.rel = 'stylesheet';
  const scriptGitalk = document.createElement('script');
  scriptGitalk.src = 'https://unpkg.com/gitalk@1/dist/gitalk.min.js';

  document.body.appendChild(linkGitalk);
  document.body.appendChild(scriptGitalk);

  router.afterEach((to, from) => {
    // 页面滚动,hash值变化,也会触发afterEach钩子,避免重新渲染
    if (to.path === from.path) return;

    // 已被初始化则根据页面重新渲染 评论区
    tryRun((next) => {
      const $page = document.querySelector('.page');
      if ($page && window.Gitalk) {
        // 如果不setTimeout取到是上一篇文档的标题
        setTimeout(() => {
          renderGitalk($page, to.path);
        }, 1);
      } else {
        next(500);
      }
    }, 10);
  });

  function renderGitalk(parentEl, path) {
    // 移除旧节点,避免页面切换 评论区内容串掉
    const oldEl = document.getElementById('comments-container');
    oldEl && oldEl.parentNode.removeChild(oldEl);

    const commentsContainer = document.createElement('div');
    commentsContainer.id = 'comments-container';
    commentsContainer.classList.add('content');
    commentsContainer.style = 'padding: 0 30px;';
    parentEl.appendChild(commentsContainer);

    const gitalk = new Gitalk({
      clientID: 'xxx', // 第一步注册 OAuth application 后获取到的 Client ID
      clientSecret: 'xxx', // 第一步注册 OAuth application 后获取到的 Clien Secret
      repo: 'fenghen.me',
      owner: 'hughfenghen',
      admin: ['hughfenghen'],
      id: location.pathname, // Ensure uniqueness and length less than 50
      distractionFreeMode: false, // Facebook-like distraction free mode
    });
    gitalk.render('comments-container');
  }
}

export default ({
  Vue, // VuePress 正在使用的 Vue 构造函数
  options, // 附加到根实例的一些选项
  router, // 当前应用的路由实例
  siteData, // 站点元数据
}) => {
  try {
    // 生成静态页时在node中执行,没有document对象
    document && integrateGitalk(router);
  } catch (e) {
    console.error(e.message);
  }
};

enhanceApp 参考文档 (opens new window)

# VuePress deploy

部署项目,如果还未部署,请参考部署文档 (opens new window)

# 注意事项

  • VuePress 构建的时候,在 node 中执行代码生成各个页面的时候,此时 document 为 undefined,所以写在 try...catch 块中,构建时必然会执行到 catch 块代码。目前没找到环境检测方法。
  • document.querySelector('.page'),page、content 是 VuePress 现在默认的 class,后续升级可能会报错,届时需要同步改一下。
  • 如果需要对本文提供的代码进行改造,renderGitalk在每次路由切换后都必须执行,Gitalk 的 ID 是页面的 fullPath,如果未执行会导致页面间评论混乱。
  • 评论之后刷新页面,如果发现评论不见了,是因为页面缓存,不用担心,可以点击 Issue Page(♡ Like 右侧)检查。
💗 博主正处于裸辞待业状态,欢迎 商务合作 💗

相关文章

从 React 看前端 UI 代码范式革命

alt text 前言 本来打算写的主题是“我为什么讨厌 React Hooks API”,展开聊聊“小甜甜”是如何变成“牛夫人”的,没想到越写越严肃:) React 是两次前端范式革命的引领者,至今仍有繁荣的社区和旺盛的创造力; React 多次天才又激进的创新,一些想法被借鉴改良、一些引发广泛质疑,大部分是被认同和接受的; ...

WebCodecs 性能表现及优化思路

笔者开源 WebAV 已经一年半,还写了系列文章帮助初学者入门 Web 音视频。 之前一直隐隐担心在 Web 平台处理音视频与 Native APP 会有明显性能差距,因为 WebCodecs API 毕竟被浏览器代理了一层,且一些数据处理需要 js 配合,不确定有多大的性能损耗。 相信刚接触 WebCodecs 的读者也非常关心它的性能表现如何。 ...

Web 网页自集成 HTTP 代理方案

前言 大部分程序员,想必都有会一个常用的抓包代理工具; 但在座的各位,可曾见过这样一款集成在 Web 应用中的代理工具? 它是明显区别于传统代理工具的,有以下特性: 零安装,零配置,Web 点击即用、APP 扫码即用;_(不 ...

Web 文件系统(OPFS 及工具)介绍

文件系统是往往是构建大型软件的基石之一,很长一段时间 Web 平台因缺失成熟的文件系统成为构建大型软件的阻碍,如今 OPFS 可弥补这一缺憾。 本文介绍 OPFS 背景和基本使用方法、使用过程中的注意事项,及如何配合笔者开源的 opfs-tools、opfs-tools-explorer 两个项目,充分发挥 OPFS 的性能与开发效率。 Web 存储 A ...

opfs-tools (文件系统 API) 项目介绍

文件系统是许多领域程序的基石,所有通用编程语言都会内置完备的文件系统 API。 Web 很长一段时间没有提供完善的访问文件系统的规范,使得需要高频读写文件、大文件处理软件在 Web 端都会受到一些限制,比如音视频剪辑、游戏、数据库等等。 之前在浏览器中实现视频裁剪、截帧等相关功能时,发现缺少基本的操作文件的 API,比如读写、移动、复制文件。 而 [OPFS] ...

Web 终极拦截技巧(全是骚操作)

拦截的价值 > 计算机科学领域的任何问题都可以通过增加一个中间层来解决。 —— Butler Lampson 如果系统的控制权、代码完全被掌控,很容易添加中间层; 现实情况我们往往无法控制系统的所有环节,所以需要使用一些 “非常规”(拦截) 手段来增加中间层。 拦截的方法 拦截/覆写 浏览器 API 最常见的场景有通过拦截 console ...

Web 音视频(六)图像素材处理

Web 音视频目录 前序章节介绍了如何在浏览器中解析、创建视频,以及给视频添加一些自定义素材(图片、音频、文字...); 本章介绍如何给图像素材加特效、加动画,实现转场、移动水印、图像滤镜美化等功能。 你可以跳过原理介绍,直接查看 WebAV 示例 素材动画 在视频制作中实现动画跟其他场景略有不同,因为视频 ...