# 搭建一个基于 VuePress 的博客/技术文档网站

# 什么是 VuePress?

VuePress 是一款基于 Vue 的静态网站生成器。它可以将你编写的 Markdown 文档转化为已经渲染好的 HTML 静态页面。这些页面有着良好的 SEO 优化,可以轻松的支持搜索引擎收录;同时页面被浏览时由 Vue 接管而形成单页应用,其他页面按浏览按需加载。

# 为什么选 VuePress?

最重要的一点是:VuePress 对 Vue 技术有着很好的支持。这也就意味着除了其他静态网站生成器的功能,你可以在文档中使用 Vue 的动态组件,这对 Vue 程序员来说十分友好。关于 Vue 组件,你可以参考这个链接:在 Markdown 中使用 Vue (opens new window)
其次是 VuePress 的默认主题,它的设计初衷是为了提供给编写产品文档的一个解决方案。也就是说,VuePress 生成的静态网页应用的风格看上去是技术文档,而不是传统博客。这更契合程序员的日常阅读习惯,同时可以让我们编写文章时操作简便且富有条理。当然,VuePress 也有官方和第三方主题,可以实现 Hexo 等技术的博客风格,可以按需安装。
VuePress 也拥有者丰富的插件库,当你需要评论功能、用 输入一些公式等,都能找到相关的插件来支持自己的需求。
这些是表层上的一些优势。关于 VuePress 和其他类似技术在底层实现和性能方面的对比可以在官方文档 (opens new window)中进行阅读。

# 技术架构

VuePress 的部署方案是多种多样的,这篇文章主要讲 VuePress + GitHub Pages 和 VuePress + Netlify 两种部署方案。其中 Netlify 是持续集成的。两种方案都不需要额外的服务器。

我们需要用到的技术:Git, VuePress, Markdown
我们需要用到的工具:GitHub, Netlify (可选)

# 开始前的建议

在我们正式开始前,我推荐:预先掌握 Git 的基础知识、Markdown 的简单语法和 GitHub 的基本使用方法、大致阅读 VuePress 官方文档。

# 搭建

# I. Git 和 GitHub

  1. 新建 Repository
    假如你还没有 GitHub 账户,注册一个,然后新建 Repository。
    仓库名称填写你希望取的域名加上 ".github.io",然后填写对这个仓库的大概描述,勾选 “Initialize this repository with a README”。

    New Repository

  2. 完善 Repository

    • 完善 README.md
      在 Repository 页面完善项目信息,点击 README.md 文件的编辑按钮进入编辑界面,使用 Markdown 语法编写对该项目更详细的描述。完成后点击 Commit changes 按钮来提交本次修改。
      Update README

    • 编写 .gitignore
      很多文件我们不需要同步到 GitHub 仓库里,使用.gitignore文件来标识出哪些文件或目录不需要同步。
      在仓库首页点击Creat new file按钮进入编辑界面。输入新建的文件名:.gitignore,并填写内容:"node_modules"。(根据你使用的 IDE 不同,也许你需要添加".vs" 或者 ".idea" 等内容来避免同步 IDE 独特的项目信息,请根据需求自行添加。)
      完成后点击 Commit changes 按钮来提交本次修改。
      .gitignore

  3. 安装和配置 Git

    • 安装并部署你的 Git
      下载并安装相关的程序,运行并配置你的账户。你可以根据廖雪峰老师的这个教程来安装。廖雪峰的官方网站-安装Git (opens new window)

    • 初始化本地仓库
      在本机上适合的位置创建一个文件夹,命名和 GitHub 创建的仓库名称一致。这个文件夹将作为我们本次项目的文件夹。
      使用 Git Bash 或者其他命令行(控制台/终端)程序访问到该文件夹,输入命令来把文件夹初始化为 git 仓库。

      git init
      
      1
    • 建立本地和远程仓库的连接
      生成本地 SSH Key,并提交 GitHub。使用命令关联远程仓库。
      具体请参考:廖雪峰的官方网站-远程仓库 (opens new window)

    • 拉取文件到本地

      git pull
      
      1

# II. 安装 VuePress

  1. 安装 Node.js
    下载并安装 Node.js (opens new window).

  2. 安装 Yarn
    使用命令行程序全局安装包管理器 Yarn.

    npm install -g yarn
    
    1
  3. 安装 VuePress
    使用命令行程序访问到之前创建的项目目录。以本地依赖形式安装。后创建 /docs 目录用来后续存放需要编写的文章。

    # 将 VuePress 作为一个本地依赖安装
    yarn add -D vuepress
    
    # 新建一个 docs 目录
    mkdir docs
    
    1
    2
    3
    4
    5

# III. 配置 VuePress

  1. 编写脚本 修改package.json文件,添加一些脚本:

    {
      "scripts": {
        "docs:dev": "vuepress dev docs",
        "docs:build": "vuepress build docs"
      }
    }
    
    1
    2
    3
    4
    5
    6

    值得注意的是

    因为是追加内容,所以需要在本原来的最后一项后加上逗号。例如:




     






    {
       "devDependencies": {
         "vuepress": "^1.3.1"
       },
       "scripts": {
         "docs:dev": "vuepress dev docs",
         "docs:build": "vuepress build docs"
       }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  2. 创建必要的文件和目录

    • 在 /docs 目录中创建目录:/.vuepress

    • 在 /.vuepress 目录中创建目录: /public

    • 在 /public 目录中创建目录: /img

    • 在 /img 目录中放入你喜欢的图片当做首页 logo,这里假设图片名为logo.png

    • 退回到 /docs 目录,创建 README.md文件,它将生成为站点首页
      参考这个示例编写:

      ---
      home: true
      heroImage: /img/logo.png
      actionText: Hello, world! →
      actionLink: /tittle-tattle/
      meta:
      - name: keywords
        content: 技术 软件 计算机 Java Web 软件工程 笔记
      features:
      - title: 全面
        details: 笔记涵盖从计算机科学、软件工程、到各种具体实用技术等多维度内容。
      - title: 简洁
        details: 笔记力图以简洁的文字和画面表现出各知识的条理关系。
      - title: 实用
        details: 这不是百科全书,但在全面的基础上尽量展示最可能用到的部分。
      footer: Copyright © 2018-2020 ahza.xin | localhost-8080.io
      ---
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      • home 标识当前页面为站点首页
      • heroImage 选定首页大图(Logo)
      • actionText 指定默认按钮文字
      • actionLink 指定默认按钮跳转的页面
      • meta 可以指定在 html 的 <meta> 中增添的信息,这里增添了关于 "keywords" 的内容
      • features 是默认的三个特性展示,通过设置 title 和 details 来完善内容
      • footer 展示页脚信息

      首页效果可以参考 VuePress 官方文档的首页。

  3. 配置文件
    在 /docs/.vuepress/ 目录下创建文件:config.js 并编写。
    参考示例:

    module.exports = {
      title: '本地煮鸡:8080',
      description: '一个博客, 大概会记录一些技术笔记',
      head: [
        ['link', { rel: 'icon', href: '/img/favicon.ico' }]
      ],
      plugins: {
        '@vuepress/pwa': {
          serviceWorker: true,
          updatePopup: {
            message: "有文章更新了",
            buttonText: "刷新"
          }
        },
        '@vuepress/back-to-top': true,
        '@vuepress/register-components': {
          componentsDir: '/components/'
        },
        '@vuepress/google-analytics': {
          'ga': 'UA-**********-*'
        }
      },
      themeConfig: {
        repo: 'ZweiRm/localhost-8080.github.io',
        repoLabel: '查看源码',
        docsDir: 'docs',
        editLinks: true,
        editLinkText: '帮助我改善此页面!',
        lastUpdated: '上次更新',
        nav: [{
          text: '主页',
          link: '/',
          },
          {
            text: '博文',
            items: [
              { text: 'Java', link: '/java/' },
              { text: 'Kotlin', link: '/kotlin/' }
            ]
          },
          { text: '关于', link: '/about/' },
          { text: 'Github', link: 'https://www.github.com/ZweiRm' },
        ],
        sidebar: {
          '/java/': [
            '',
            'grammar',
            'object-oriented',
            'application-programming-interface'
          ],
          '/kotlin/': [
              '',
          ]
        },
        sidebarDepth: 2
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    • title
      网站的标题。

    • description
      网站的描述,它会被渲染在 html 的 <meta> 中。

    • head
      这里设置的值会被渲染在 html 的 <head> 中,示例中设置了网站的 favicon(即浏览器标签里网站的小图标)。

    • plugins
      设置并启用插件,这里设置了官网插件:pwa, back-to-top, register-components 和 google-analytics.
      具体设置及使用方法参照:插件 | VuePress (opens new window)

    • themeConfig
      配置默认主体。在这个示例中,配置了 Git 仓库和编辑链接、最后更新时间、导航栏、侧边栏(多层嵌套式)。具体设置及使用方法参照:默认主题配置 | VuePress (opens new window)

      注意

      • 关于侧边栏
        侧边栏的配置和你的 /docs 目录息息相关,二者应当是相互对应的。例如:

        在这个示例配置文件中,sidebar 配置了一些文章,它们表达的意思是:Java 项下有文章《README》(即空字符串)、《语法》、《面向对象》、《应用程序编程接口概述》;在 Kotlin 项下有文章《README》。它们所对应的目录结构将在下一小节中展示。

        由于这里对每篇文章手动设置了侧边栏,所以后面每次当我们需要撰写新的文章时都需要通过调整这个配置来显示正确的侧边栏。

        文章分类目录为英文时,为了避免不必要的烦恼推荐写为小写英文,它们将会被映射为 url (即单引号中的内容,如'/deep-learning/')。

        在实际所生成的侧边栏(即通过命令进入开发模式或者生成静态文件后所显示的)中,显示内容为具体文档的一级标题而不是侧边栏设置中配置的字符串。例如:当 config.js 中侧边栏配置了 '面向对象',而在 面向对象.md 文档中的一级标题为 # Object-Oriented 时,实际生成页面中的侧边栏所显示的内容为 "Objec-Oriented".

        值得注意的是,这里推荐使用英文来命名每一篇 Markdown 文档。因为它将被映射为 url 中的一部分, 而中文需要被转码以后才能作为 url,所以这会使得整个 url 变得异常地长。

      • 关于导航栏
        一般读者需要通过导航栏来访问具体类目中的文章。在这个示例配置文件中,配置了普通链接,如:主页,它所对应的链接是 /;嵌套链接,如:博文,它还包含了 JavaKotlin 子项。

    这里只介绍有用且相对必要的配置,其他配置项及配置项的详细信息请参照:配置 | VuePress (opens new window)

    从 0.x 迁移

    假如你按照其他 0.x 版本的 VuePress 安装过了,并渴望使用新的 1.x 版本 VuePress,请参照文章 从 VuePress 0.x 迁移 | VuePress (opens new window) 来配置。

  4. 目录结构
    到此,你已经可以通过使用命令行程序运行命令来进入开发模式进行文章的撰写了:

    yarn docs:dev
    
    1

    我们此时的目录结构为:

    · (whatever-you-like.github.io)
    ├── docs
    │   ├── .vuepress
    │   │   ├── public
    │   │   │   └── img
    |   |   ├── config.js
    |   |   └── dist (使用页面生成命令后,静态页面将会生成在这里,这个目录也会自动生成)
    |   ├── java
    |   |   ├── README.md
    |   |   ├── grammar.md
    |   |   ├── object-oriented.md
    |   |   └── application-programming-interface.md
    |   └── kotlin
    |       └── README.md
    ├── node_modules
    ├── package.json
    ├── yarn.lock
    ├── README.md
    ├── .gitignore
    └── .git
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    在开发模式下,你可以在 /docs 目录下通过新建 .md 文件来新建一篇文章,通过新建一个目录来新建一个分类。完成后同步修改 .vuepress/config.js 中相关导航栏和侧边栏配置。

    当你在编写一篇文章时,每当保存了 .md 文件,结果会自动更新在浏览器页面中。

    当我们完成文章的编写后,我们需要生成静态网页并部署到服务器中,实现互联网访问我们的网站。这里提供两种方法,一个是拥有持续集成功能的 Netlify 方案,一个是手动操作的 GitHub Pages 方案,我们将分为两节描述它们。

# 部署 - Netlify

Netlify 提供了一种十分方便的持续集成体验。也就是说,每当你 push 你的新文章到 GitHub 后,Netlify 可以自动帮你生成静态页面文件并部署。但它的缺点也十分明显,由于一些特殊的网络原因,由 Netlify 部署的网站访问速度会极其缓慢甚至无法加载。

当我们注册好 Netlify 后,对其进行一些简单的配置:

  1. 同步我们的代码到 GitHub
    首先通过命令把我们之前写过的所有内容同步到 GitHub 上的远程仓库。

    git add -A
    git commit -m 'deploy'
    
    # 将<USERNAME>/<USERNAME>.github.io.git 修改为你的仓库
    git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master
    
    1
    2
    3
    4
    5
  2. 创建新网站

    • 点击New site from Git按钮创建新网站。点击 GitHub 按钮连接我们的项目仓库。
      Create a new site
    • 选择我们的远程仓库
    • 填写配置信息:Build command, Publish directory
      Build Options
    • 点击 Deploy site 按钮

Netlify 还有一些其他的设置,比如域名配置、DNS 配置等,你可以根据需求自行阅读相关说明并进行设置。

# 部署 - GitHub Pages

我们可以使用 GitHub 自带的 GitHub Pages 来实现部署,它使用 GitHub 的服务器,一般情况下不会出现复杂的网络问题。

  1. 生成静态网页文件
    使用命令来生成文档:

    yarn docs:build
    
    1

    将生成在 whatever-you-like.github.io/docs/.vuepress/dist 中的所有文件复制并粘贴到项目文档的根目录(即 whatever-you-like.github.io)中。

  2. 同步我们的代码到 GitHub
    通过命令把我们之前写过的所有内容同步到 GitHub 上的远程仓库。

    git add -A
    
    # 引号中的字符串可以根据实际情况进行修改
    git commit -m 'deploy'
    
    # 将<USERNAME>/<USERNAME>.github.io.git 修改为你的仓库
    git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master
    
    1
    2
    3
    4
    5
    6
    7
  3. 设置 GitHub Pages
    进入 GitHub 中,点击我们的项目仓库并点击设置按钮。找到 GitHub Pages 选项,修改设置:Source 项选中:master branch,勾选 Enforce HTTPS.
    GitHub Pages
    如果你拥有自己注册的域名并希望使用在这个网站上,可以将它填写在 Custom domain 中。

注意

当你使用本方法来部署你的网页,每当你希望更新你的网站页面时,你都需要手动进行以下操作:

  1. 使用命令来生成静态页面:

    yarn docs:build
    
    1
  2. 将生成在 whatever-you-like.github.io/docs/.vuepress/dist 中的所有文件复制并粘贴到项目文档的根目录(即 whatever-you-like.github.io)中

  3. 使用命令来提交你的代码到 GitHub 远程仓库:

    git add -A
    
    # 引号中的字符串可以根据实际情况进行修改
    git commit -m 'deploy'
    
    # 将<USERNAME>/<USERNAME>.github.io.git 修改为你的仓库
    git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master
    
    1
    2
    3
    4
    5
    6
    7

当然你也可以在本地配置 Jenkins 等持续集成方案来实现自动部署,在这篇文章中不再赘述。

# 你可能会遇到的问题

  1. Q: 为什么我在两篇文章之间设置了链接,但点击无法访问到?
    A: 当编写多篇文章之间的链接时,格式为[链接文字](./文章名.html#章节名)。即比文章内链接多了两项:./文章名.html。特别需要注意的是文章名后有 ".html" 的。

  2. Q: 如何解决每次手动输入 Git 命令的麻烦?
    A: 推荐使用 IDE 来编写你的文章,比如使用 Visual Studio Code 或者 IntelliJ IDEA 等 IDE. 它们很好的支持了版本控制软件 Git,可以通过相对可视化的操作来简化你在 Git 方面的操作,这会让你日常书写体验变得更好。

  3. Q: 如何修改一部分样式而不使用其他主题或者自己编写主题?
    A: 以修改 code 样式字体为例:

    1. /.vuepess文件夹下新建文件夹/styles.
    2. /styles文件夹下新建文件index.styl.
    3. 编辑index.styl,使用 css 语法或者 stylus 语法编写样式。 例如:
      code, kbd, .line-number
        font-family "JetBrains Mono", source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace
      @font-face
         font-family "JetBrains Mono"
         src url("/font/JetBrainsMono-Regular.woff")
      
      1
      2
      3
      4
      5

    此时的/.vuepress目录结构为:

      .vuepress
      ├── public
      |   ├── font (用于存放字体文件,这体现在`.styl`文件的`src url("...")`项里)
      │   └── img
      ├── config.js
      └── dist
    
    1
    2
    3
    4
    5
    6
  4. Q: 我修改了侧边栏配置,而且确定正确修改了对应的 Markdown 文档的名称,dev 模式也能正确看到文章。但为什么使用 build 命令生成网页时不断报错?
    A: 请检查 Markdown 文档中 front-matter 的 prevnext 项是否也正确修改。

  5. Q: 为什么我的侧边栏不显示?
    A: 请认真检查是否正确配置侧边栏相关的内容,如文件夹命名、文档命名、congfig.js 中相关配置项是否正确(如是否漏写两边任意的/)。

  6. Q: 当我试图启动 VuePress 时提示项目系统文件 "isDebug; SyntaxError: Unexpected token ;" 错误。
    A: 请尝试更新您的 Node.js 到更新的版本。此问题也会出现在 Netlify 部署中。对于 Netlify, 请在设置中增添环境变量:NODE_VERSION 为合适的版本。

# 参考文献或资料

[1] Evan You.VuePress (opens new window)
[2] 廖雪峰.廖雪峰的官方网站-Git教程 (opens new window)
[3] destiny0904.VuePress 入门 (opens new window)