1. 程式人生 > >Leader 讓我做 CMS 幫助中心的技術選型,我擼了 VuePress 和 GitBook,然後選擇...

Leader 讓我做 CMS 幫助中心的技術選型,我擼了 VuePress 和 GitBook,然後選擇...

前言

因為自己平時經常寫部落格,也有部落格網站,所以 Leader 叫我做一個 CMS 的幫助中心的技術選型,CMS 的幫助中心的功能:是通過文章來教使用者如何使用我們的專案。

所以筆者要做一個靜態網站的技術選型,筆者把網上流行的 VuePressGitBook 兩種方式都嘗試了一下,並做了對比,這裡寫篇文章總結一下,順便把自己的部落格網站重作一便,哈哈。

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 SSRHTML 模板檔案。
  • docs/.vuepress/config.js: 配置檔案的入口檔案,也可以是 YMLtoml
  • docs/.vuepress/enhanceApp.js: 客戶端應用的增強。

注意:

  1. 當你想要去自定義 templates/ssr.html 或 templates/dev.html 時,最好基於 預設的模板檔案 來修改,否則可能會導致構建出錯。

  2. 還有就是筆者的  templates/ssr.html 和 templates/dev.html 是有新增如下這一行程式碼的:

<meta id="referrer" name="referrer" content="never" />

因為筆者的圖片都是存在簡書上的,所以為了可以訪問第三方圖床的圖片,才添加了這句程式碼,如果你的圖片是存在本地的,去掉這句程式碼即可,至於具體原因請看筆者寫的文章:前端解決第三方圖片防盜鏈的辦法 - html referrer 訪問圖片資源403問題 。

  1. 筆者的目錄也是按官方推薦的來的,如下:

1.5 評論

評論功能用了 GitTalk。

1.5.1 申請一個 OAuth App

具體實踐如下:

  1. 首先登入你的 GitHub 賬號,然後點選進入Settings。

  1. 點選 OAuth Apps , Register a new application 或者 New OAuth App 。

  1. 輸入資訊。

  1. 應用資訊說明:Client ID && Client Secret

建立成功有 Client IDClient Secret ,儲存下來,後面我們會用到。

  1. 建立評論元件

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>
  1. 使用評論元件

理論上,我們在每個 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.jsonscripts, 先為每個 md 檔案新增元件,然後打包,最後再一一刪除 markdown 中的 comment 元件。

"build": "node ./builds/addComponents.js && vuepress build docs && node ./builds/delComponents.js",

筆者的專案裡面是把添加了二條命令的,比如 npm run dev:mdnpm 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"
  },

想要怎樣的打包命令,自己修改就行。

  1. 注意:如果你的文章的評論要和 githubissues 的同步的話,還要在 issueslabel 裡新增相應的 pathnamegitalk,其中 pathname 就是評論元件裡面的 location.pathname

比如我的:

1.6 部署到 Github pages

當我們將文件寫好後就到了我們最關心的地方了,怎麼將打包後的程式碼推送到遠端倉庫的 gh-pages 分支上。

  1. 建立一個deploy.sh
touch deploy.sh
  1. 編寫指令碼
#!/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 [email protected]:<USERNAME>/<USERNAME>.github.io.git master

# 如果釋出到 https://<USERNAME>.github.io/<REPO>
# git push -f [email protected]:<USERNAME>/<REPO>.git master:gh-pages

cd -
  1. 設定 package.json
{
    "scripts": {
        "deploy": "bash deploy.sh"
      },
}
  1. 釋出
npm run deploy   // 即可自動構建部署到 github 上。
  1. 訪問自己的域名,比如筆者的: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 buildgitbook serve 自動生成的.
  • book.json 是配置檔案,用於個性化調整 gitbook 的相關配置,如定義電子書的標題、封面、作者等資訊。雖然是手動建立但一般是必選的.
  • GLOSSARY.md 是預設的詞彙表,主要說明專業詞彙的詳細解釋,這樣閱讀到專業詞彙時就會有相應提示資訊,也是手動建立但是可選的.
  • LANGS.md 是預設的語言檔案,用於國際化版本翻譯和 GLOSSARY.md 一樣是手動建立但是可選的.

book.json 的意思:

  1. title:網站標題
  2. author:網站作者
  3. description:網站功能描述
  4. language:網站使用語言
  5. styles:網站額外配置的樣式表
  6. plugins:網站使用的外掛
  7. 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 &copy 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

相同點

  1. 目前只支援 markdown 格式,圖片、視訊 等靜態資源可以儲存在本地,或者儲存到允許訪問的第三方服務商(如七牛雲);
  2. 如果是 world 文件或者 html 格式,要轉換成 md 格式才行。
  3. 找了幾個 world 文件轉換成 md 格式的工具,都不好用,特別是有原文件有圖片的時候。

不同點

  1. GitBook 的配置成本很小,可以本地編輯,然後直接部署;GitBook 官方還有個線上編輯器,不過內容要存在 GitBook 的伺服器上。
  2. VuePress 的配置成本稍稍大一點,不過可以使用 Vue 的語法與元件,定製化更自由一點,而且 VuePress 中編寫 Vue 和平時一樣,學習成本幾乎為零,可以本地用 VsCode 編輯,然後直接命令列部署。

結論

  1. 都要用 markdown 語法來寫文章,markdown 也就幾個常用語法而已,非常簡單上手。
  2. 非技術人員推薦用 GitBook,技術人員推薦用 VuePress,特別是前端技術人員。
  3. 個人更喜歡 VuePress

4. 專案原始碼

本文中使用 VuePressGitBook 的搭建的完整示例程式碼都已經上傳到 GitHub 上了,可以自行下載來用。

只要把其中的一些配置資訊換成自己的就行,比如 倉庫Client ID && Client Secret、作者等。

原始碼地址: https://github.com/biaochenxuying/blog 。

其中 VuePressGitBook 的示例程式碼都在 blog-gitbookblog-vuepress 裡面了。

這次需求的結果

令筆者吐血的是:花了 3 天搞的調研,最後 leader 沒有采用