Leader 让我做 CMS 帮助中心的技术选型,我撸了 VuePress 和 GitBook,然后选择...

前言
因为自己平时经常写博客,也有博客网站,所以 Leader 叫我做一个 CMS 的帮助中心的技术选型,CMS 的帮助中心的功能:是通过文章来教用户如何使用我们的项目。
所以笔者要做一个静态网站的技术选型,笔者把网上流行的 VuePress 和 GitBook 两种方式都尝试了一下,并做了对比,这里写篇文章总结一下,顺便把自己的博客网站重作一便,哈哈。

1. VuePress
1.1 简介
VuePress 是 Vue 驱动的静态网站生成器。
简洁至上
以 Markdown 为中心的项目结构,以最少的配置帮助你专注于写作。
Vue 驱动
享受 Vue + webpack 的开发体验,可以在 Markdown 中使用 Vue 组件,又可以使用 Vue 来开发自定义主题。
高性能
VuePress 会为每个页面预渲染生成静态的 HTML,同时,每个页面被加载的时候,将作为 SPA 运行。
1.2 效果
首页:

评论:

效果详情请看:https://biaochenxuying.github.io/blog/ 。
1.3 简单使用
像数 1, 2, 3 一样容易
# 安装
yarn global add vuepress # 或者:npm install -g vuepress
# 创建项目目录
mkdir vuepress-starter && cd vuepress-starter
# 新建一个 markdown 文件
echo '# Hello VuePress!' > README.md
# 开始写作
vuepress dev .
# 构建静态文件
vuepress build .
1.4 目录结构
VuePress 遵循 “约定优于配置” 的原则,推荐的目录结构如下:
├── docs
│ ├── .vuepress (可选的)
│ │ ├── components (可选的)
│ │ ├── theme (可选的)
│ │ │ └── Layout.vue
│ │ ├── public (可选的)
│ │ ├── styles (可选的)
│ │ │ ├── index.styl
│ │ │ └── palette.styl
│ │ ├── templates (可选的, 谨慎配置)
│ │ │ ├── dev.html
│ │ │ └── ssr.html
│ │ ├── config.js (可选的)
│ │ └── enhanceApp.js (可选的)
│ │
│ ├── README.md
│ ├── guide
│ │ └── README.md
│ └── config.md
│
└── package.json
注意:请留意目录名的大写。
docs/.vuepress: 用于存放全局的配置、组件、静态资源等。docs/.vuepress/components: 该目录中的Vue组件将会被自动注册为全局组件。docs/.vuepress/theme: 用于存放本地主题。docs/.vuepress/styles: 用于存放样式相关的文件。docs/.vuepress/styles/index.styl: 将会被自动应用的全局样式文件,会生成在最终的CSS文件结尾,具有比默认样式更高的优先级。docs/.vuepress/styles/palette.styl: 用于重写默认颜色常量,或者设置新的stylus颜色常量。docs/.vuepress/public: 静态资源目录。docs/.vuepress/templates: 存储HTML模板文件。docs/.vuepress/templates/dev.html: 用于开发环境的HTML模板文件。docs/.vuepress/templates/ssr.html: 构建时基于Vue SSR的HTML模板文件。docs/.vuepress/config.js: 配置文件的入口文件,也可以是YML或toml。docs/.vuepress/enhanceApp.js: 客户端应用的增强。
注意:
当你想要去自定义
templates/ssr.html或templates/dev.html时,最好基于 默认的模板文件 来修改,否则可能会导致构建出错。还有就是笔者的
templates/ssr.html和templates/dev.html是有添加如下这一行代码的:
<meta id="referrer" name="referrer" content="never" />
因为笔者的图片都是存在简书上的,所以为了可以访问第三方图床的图片,才添加了这句代码,如果你的图片是存在本地的,去掉这句代码即可,至于具体原因请看笔者写的文章:前端解决第三方图片防盗链的办法 - html referrer 访问图片资源403问题 。
- 笔者的目录也是按官方推荐的来的,如下:

1.5 评论
评论功能用了 GitTalk。
1.5.1 申请一个 OAuth App
具体实践如下:
- 首先登录你的 GitHub 账号,然后点击进入Settings。

- 点击 OAuth Apps , Register a new application 或者 New OAuth App 。

- 输入信息。

- 应用信息说明:
Client ID&&Client Secret

创建成功有 Client ID 和 Client Secret ,保存下来,后面我们会用到。
- 创建评论组件
Vuepress 默认 .vuepress / components 文件夹下的组件会全局注册,因此我们创建一个 comment 组件。
gittalk.css 请点击 这里
<template>
<div class="gitalk-container">
<div id="gitalk-container"></div>
</div>
</template>
<script>
export default {
name: 'comment',
data() {
return {};
},
mounted() {
let body = document.querySelector('.gitalk-container');
let script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js';
body.appendChild(script);
script.onload = () => {
const commentConfig = {
clientID: '你的clientID',
clientSecret: '你的clientSecret',
repo: '你的仓库名称',
owner: '你的用户名',
// 这里接受一个数组,可以添加多个管理员,可以是你自己
admin: ['管理用户名'],
// id 用于当前页面的唯一标识,一般来讲 pathname 足够了,
// 但是如果你的 pathname 超过 50 个字符,GitHub 将不会成功创建 issue,此情况可以考虑给每个页面生成 hash 值的方法.
id: location.pathname,
distractionFreeMode: false,
};
const gitalk = new Gitalk(commentConfig);
gitalk.render('gitalk-container');
};
},
};
</script>
<style>
@import '../css/gittalk.css';
</style>
- 使用评论组件
理论上,我们在每个 markdown 文件里直接加入这个组件即可,但是每次都添加有点麻烦,还是让 node 来帮我们吧
根目录创建 build 文件夹, 创建三个文件 addComponents.js, delComponents.js, findMarkdown.js, 分别代码如下:
// addComponents.js
const fs = require("fs");
const findMarkdown = require("./findMarkdown");
const rootDir = "./docs";
findMarkdown(rootDir, writeComponents);
function writeComponents(dir) {
if (!/README/.test(dir)) {
fs.appendFile(dir, `\n \n <comment/> \n `, err => {
if (err) throw err;
console.log(`add components to ${dir}`);
});
}
}
// delComponents.js
const fs = require("fs");
const findMarkdown = require("./findMarkdown");
const rootDir = "./docs";
findMarkdown(rootDir, delComponents);
function delComponents(dir) {
fs.readFile(dir, "utf-8", (err, content) => {
if (err) throw err;
fs.writeFile(
dir,
content.replace(/\n \n <comment\/> \n /g, ""),
err => {
if (err) throw err;
console.log(`del components from ${dir}`);
}
);
});
}
// findMarkdown.js
const fs = require("fs");
function findMarkdown(dir, callback) {
fs.readdir(dir, function(err, files) {
if (err) throw err;
files.forEach(fileName => {
let innerDir = `${dir}/${fileName}`;
if (fileName.indexOf(".") !== 0) {
fs.stat(innerDir, function(err, stat) {
if (stat.isDirectory()) {
findMarkdown(innerDir, callback);
} else {
// 跳过readme 文件,当然你也可以自行修改
if (/\.md$/.test(fileName) && !/README/.test(fileName))
callback(innerDir);
}
});
}
});
});
}
module.exports = findMarkdown;
修改 package.json 的 scripts, 先为每个 md 文件添加组件,然后打包,最后再一一删除 markdown 中的 comment 组件。
"build": "node ./builds/addComponents.js && vuepress build docs && node ./builds/delComponents.js",
笔者的项目里面是把添加了二条命令的,比如 npm run dev:md 和 npm run build:md 才是有评论组件的。
"scripts": {
"dev": "vuepress dev docs",
"dev:md": "node ./builds/addComponents.js && vuepress dev docs && node ./builds/delComponents.js",
"docs:dev": "vuepress dev docs",
"build": "vuepress build docs",
"build:md": "node ./builds/addComponents.js && vuepress build docs && node ./builds/delComponents.js",
"docs:build": "vuepress build docs",
"delay": "bash delay.sh",
"test": "echo \"Error: no test specified\" && exit 1"
},
想要怎样的打包命令,自己修改就行。
- 注意:如果你的文章的评论要和
github的issues的同步的话,还要在issues的label里添加相应的pathname和gitalk,其中pathname就是评论组件里面的location.pathname。
比如我的:

1.6 部署到 Github pages
当我们将文档写好后就到了我们最关心的地方了,怎么将打包后的代码推送到远程仓库的 gh-pages 分支上。
- 创建一个deploy.sh
touch deploy.sh
- 编写脚本
#!/usr/bin/env sh
# 确保脚本抛出遇到的错误
set -e
# 生成静态文件
npm run docs:build
# 进入生成的文件夹
cd docs/.vuepress/dist
# 如果是发布到自定义域名
# echo 'www.example.com' > CNAME
git init
git add -A
git commit -m 'deploy'
# 如果发布到 https://<USERNAME>.github.io
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master
# 如果发布到 https://<USERNAME>.github.io/<REPO>
# git push -f git@github.com:<USERNAME>/<REPO>.git master:gh-pages
cd -
- 设置
package.json
{
"scripts": {
"deploy": "bash deploy.sh"
},
}
- 发布
npm run deploy // 即可自动构建部署到 github 上。
- 访问自己的域名,比如笔者的:https://biaochenxuying.github.io/blog/ 。
详情移步 vuepress 官网 vuepress.vuejs.org。
2. GitBook
效果:

效果详情请看:http://biaochenxuying.cn:2021。
2.1 GitBook 常用指令
- 安装 GitBook:
npm i gitbook-cli -g - 初始化 GitBook 项目:
gitbook init - 安装 GitBook 依赖:
gitbook install - 开启 GitBook 服务:
gitbook serve - 打包 GitBook 项目:
gitbook build - GitBook 命令行查看:
gitbook -help - GitBook 版本查看:
gitbook -V
2.2 简单上手
然后,我们找个空文件夹,初始化一个 GitBook 项目。
gitbook init初始化 README.md 和 SUMMARY.md 两个文件.gitbook build本地构建但不运行服务,默认输出到 _book/ 目录.gitbook serve本地构建并运行服务,默认访问 http://localhost:4000 实时预览.
- GitBook
- README.md
- SUMMARY.md

README.md是默认首页文件,相当于网站的首页index.html,一般是介绍文字或相关导航链接.SUMMARY.md是默认概括文件,主要是根据该文件内容生成相应的目录结构,同README.md一样都是被gitbook init初始化默认创建的重要文件._book是默认的输出目录,存放着原始markdown渲染完毕后的html文件,可以直接打包到服务器充当静态网站使用。一般是执行gitbook build或gitbook serve自动生成的.book.json是配置文件,用于个性化调整gitbook的相关配置,如定义电子书的标题、封面、作者等信息。虽然是手动创建但一般是必选的.GLOSSARY.md是默认的词汇表,主要说明专业词汇的详细解释,这样阅读到专业词汇时就会有相应提示信息,也是手动创建但是可选的.LANGS.md是默认的语言文件,用于国际化版本翻译和GLOSSARY.md一样是手动创建但是可选的.
book.json 的意思:
title:网站标题author:网站作者description:网站功能描述language:网站使用语言styles:网站额外配置的样式表plugins:网站使用的插件pluginsConfig:网站使用的插件的额外配
笔者的 book.json:
{
"title": "夜尽天明的博客",
"author": "biaochenxuying",
"description": "大前端技术为主,读书笔记、随笔、理财为辅,做个终身学习者。",
"language": "zh-hans",
"plugins": [
"-highlight",
"copy-code-button",
"search-pro",
"-search",
"-lunr",
"expandable-chapters",
"splitter",
"-sharing",
"github-buttons",
"donate",
"tbfed-pagefooter",
"baidu-tongji",
"anchor-navigation-ex"
],
"pluginsConfig": {
"github-buttons": {
"buttons": [
{
"user": "biaochenxuying",
"repo": "blog",
"type": "star",
"count": true,
"size": "small"
},
{
"user": "biaochenxuying",
"width": "160",
"type": "follow",
"count": true,
"size": "small"
}
]
},
"donate": {
"button": "打赏",
"wechatText": "微信打赏",
"wechat": "https://camo.githubusercontent.com/ee094d402f957e5d656a399b9dc50ff8c010114e/68747470733a2f2f75706c6f61642d696d616765732e6a69616e7368752e696f2f75706c6f61645f696d616765732f31323839303831392d666661623762643234643038633030642e6a7065673f696d6167654d6f6772322f6175746f2d6f7269656e742f7374726970253743696d61676556696577322f322f772f31323430"
},
"tbfed-pagefooter": {
"copyright":"Copyright © biaochenxuying.cn 2019",
"modify_label": "该文件修订时间:",
"modify_format": "YYYY-MM-DD HH:mm:ss"
},
"baidu-tongji": {
"token": "XXXXX"
},
"anchor-navigation-ex": {
"showLevel": false
}
}
}
2.3 插件
插件的配置可以说是 GitBook 的核心。
详情可以看 GitBook - 快速打造可留言的博客,这里就不展开讲了。
3. VuePress VS GitBook
相同点
- 目前只支持
markdown格式,图片、视频 等静态资源可以保存在本地,或者保存到允许访问的第三方服务商(如七牛云); - 如果是
world文档或者html格式,要转换成md格式才行。 - 找了几个
world文档转换成 md 格式的工具,都不好用,特别是有原文档有图片的时候。
不同点
GitBook的配置成本很小,可以本地编辑,然后直接部署;GitBook官方还有个在线编辑器,不过内容要存在GitBook的服务器上。VuePress的配置成本稍稍大一点,不过可以使用Vue的语法与组件,定制化更自由一点,而且VuePress中编写Vue和平时一样,学习成本几乎为零,可以本地用 VsCode 编辑,然后直接命令行部署。
结论
- 都要用
markdown语法来写文章,markdown也就几个常用语法而已,非常简单上手。 - 非技术人员推荐用
GitBook,技术人员推荐用VuePress,特别是前端技术人员。 - 个人更喜欢
VuePress。
4. 项目源码
本文中使用 VuePress 和 GitBook 的搭建的完整示例代码都已经上传到 GitHub 上了,可以自行下载来用。
只要把其中的一些配置信息换成自己的就行,比如 仓库、Client ID && Client Secret、作者等。
源码地址: https://github.com/biaochenxuying/blog 。
其中 VuePress 和 GitBook 的示例代码都在 blog-gitbook 和 blog-vuepress 里面了。

这次需求的结果
令笔者吐血的是:花了 3 天搞的调研,最后 leader 没有采用
Leader 让我做 CMS 帮助中心的技术选型,我撸了 VuePress 和 GitBook,然后选择...的更多相关文章
- 泥瓦匠想做一个与众不同的技术"匠"
点击蓝字,关注泥瓦匠 本文阅读大约 3 分钟.感谢阅读 喝了最后一口百事可乐,想到它的 slogan:新一代的选择.新一代的选择,每个人选择不同,人生道路历程也不同.就像我刚毕业的时候,毕业选择不一样 ...
- #数据技术选型#即席查询Shib+Presto,集群任务调度HUE+Oozie
郑昀 创建于2014/10/30 最后更新于2014/10/31 一)选型:Shib+Presto 应用场景:即席查询(Ad-hoc Query) 1.1.即席查询的目标 使用者是产品/运营/销售 ...
- Atitit 开发2d游戏的技术选型attilax总结
Atitit 开发2d游戏的技术选型attilax总结 1.1. 跨平台跨平台:一定要使用跨平台的gui技术,目前最好的就是h5(canvas,webgl,dom) +js了..1 1.2. 游戏前后 ...
- 《2016ThoughtWorks技术雷达峰会----js爆炸下的技术选型》
JS爆炸下的技术选型 刘尚奇 ThoughtWorks, 高级咨询师 JS每6个星期出现一个新框架,那么如何进行JS的选型.以下从四个方面来分析. 1.工具 NPM for all the t ...
- 手机web站点和手机app 技术选型的困惑于思考
今年一直在关注移动端技术的发展,自己也用博客园的rss接口玩了半年,关于技术选型的困惑和大家说说 一 趋势 随着手机硬件不断的升级,外加4g牌照的发放,不出2年时间移动端web站点和手机app一定会进 ...
- atitit.技术选型方法总结为什么java就是比.net有前途
atitit.技术选型方法总结为什么java就是比.net有前途 #----按照不同的需要有不铜的法... 一般有开发效率,稳定性上的需要.. 作者 老哇的爪子 Attilax 艾龙, EMAIL: ...
- 消息中间件的技术选型心得-RabbitMQ、ActiveMQ和ZeroMQ
消息中间件的技术选型心得-RabbitMQ.ActiveMQ和ZeroMQ 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs RabbitMQ.Active ...
- (转).net项目技术选型总结
原文作者:mcgrady 原文地址:.net项目技术选型总结 做.net开发已经几年了,也参与开发了很多大大小小的项目,所以现在希望总结出一套开发.net项目的常用技术,也为以后做项目技术选型的时候作 ...
- 【SSM之旅】Spring+SpringMVC+MyBatis+Bootstrap整合基础篇(一)项目简介及技术选型相关介绍
试水 一直想去搭建个自己的个人博客,苦于自己的技术有限,然后也个人也比较懒散.想动而不能动,想动而懒得动,就这么一直拖到了现在.总觉得应该把这几年来的所学总结一番,这样才能有所成长. 不知在何时,那就 ...
随机推荐
- 原生JS实现集合结构
1. 前言 集合是由一组无序且唯一(即不能重复)的项组成的.你可以把集合想象成一个既没有重复元素,也没有顺序概念的数组.在ES6中已经内置了集合这一数据结构--Set.接下来,我们就用原生JS来实现这 ...
- python经典算法题:无重复字符的最长子串
题目:无重复字符的最长子串. 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子 ...
- 201871010114-李岩松《面向对象程序设计(java)》第十二周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 红帽7.4(RHCE7.4)磁盘扩容详细步骤
参照博文VMware虚拟机CentOS 7 磁盘扩容:https://www.linuxidc.com/Linux/2019-04/158346.htm 01.虚拟机扩容磁盘.如下图 02.使用roo ...
- mysql查询不重复的行内容,不重复的记录数.count,distinct
有这么一个表 记录了id, p_id, p_name , p_content , p_time 1 343 aaa aaaaaa 2012-09-01 2 ...
- hdu 1530 Maximum Clique (最大包)
Maximum CliqueTime Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- 调用RESTful GET方法
package restclient; import java.io.BufferedReader; import java.io.IOException; import java.io.InputS ...
- error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'
用Python打开图像始终提示错误 error: OpenCV(4.1.1) C:\projects\opencv-python\opencv\modules\highgui\src\window.c ...
- SpringBoot 正式环境必不可少的外部化配置
前言 <[源码解析]凭什么?spring boot 一个 jar 就能开发 web 项目> 中有读者反应: 部署后运维很不方便,比较修改一个 IP 配置,需要重新打包. 这一点我是深有体会 ...
- JavaWeb03-请求和响应
请求响应流程图 response 1 response概述 response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServl ...