个人博客快速搭建方案-VuePress

1. 前言

之前在EJS的文章中就提到过VuePress,特色是可以在Markdown中使用Vue组件,又可以使用Vue来开发自定义主题,对于一个前端玩家来说,Vue在当下可是必备的技能,所以使用Vue搭建博客也是一个非常常见的需求。

1.1 如何工作

一个 VuePress 网站是一个由 VueVue Routerwebpack 驱动的单页应用。

在构建时,我们会为应用创建一个服务端渲染(SSR)的版本,然后通过虚拟访问每一条路径来渲染对应的HTML

关于服务端渲染(SSR)我在Vue服务器渲染优秀项目:Nuxt.js这篇文章中有详细的提到Vue项目如何实现SSR以及为什么要使用SSR

2. 快速入门

  1. 创建并进入一个新目录

    mkdir vuepress-starter && cd vuepress-starter
  2. 使用你喜欢的包管理器进行初始化,运行下面的命令后会出现一些选项,通常一路回车过去就可以。

    npm init
    
    # 如果使用了yarn就使用下面的命令
    yarn init
  3. VuePress 安装为本地依赖

    npm install -D vuepress
    
    # 如果使用了yarn就使用下面的命令
    yarn add -D vuepress
  4. 创建你的第一篇文档

    mkdir docs && echo '# Hello VuePress' > docs/README.md
  5. package.json 中添加一些 scripts。

    注意:如果没有进行添加,下面的一些命令将无法使用,比如npm run docs:dev

    {
      "scripts": {
        "docs:dev": "vuepress dev docs",
        "docs:build": "vuepress build docs"
      }
    }
  6. 在本地启动服务器

    npm run docs:dev
    
    # 如果使用了yarn就使用下面的命令
    yarn docs:dev

最后访问locolhost:8080就可以看到已经部署完毕的博客界面了,然后就可以看到这个界面:

image-20200711143752811

是不是非常的简陋,如果要使你的博客看上去更丰富,那么就接着往下看。

3. 目录结构

根据官方文档的说明,推荐使用以下目录结构,尽量不要自行胡乱创建目录结构。

.
├── 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: 配置文件的入口文件,也可以是 YMLtoml
  • docs/.vuepress/enhanceApp.js: 客户端应用的增强。

3.1 路由

所有的“文件的相对路径”都是相对于 docs 目录的,也就是docs目录就是根目录。

文件的相对路径 页面路由地址
/README.md /
/guide/README.md /guide/
/config.md /config.html

3.2 创建.vuepress

根据上面的目录结构,我们需要在docs文件夹下创建一个.vuepress文件夹,好用来存放 VuePress 相关的文件。

然后在.vuepress文件夹下创建一个config.js文件,用来存放vuepress相关的配置,基础内容如下:

module.exports = {
  title: 'Hello VuePress',
  description: 'Just playing around'
}

重新运行一下项目后,你就会看到页面上多出了一个标题。

image-20200711144433535

但是这样看起来还是很简陋,不用担心,VuePress 可以默认主题也可以使用人家已经发布的主题。

3.3 创建public文件夹

在写作的过程中或者搭建界面的过程中经常会使用到一些图片或者其它的静态资源,这些静态资源都统一存放在public文件夹下面,例如:

image-20200711151142211

下面这张hero.png的图片,就可以通过localhost:8080/hero.png进行访问。

4. 默认主题配置

4.1 首页配置

使用默认主题配置首页需要在根级README.mdYAML front matter指定home: true。如下所示:

---
home: true
heroImage: /hero.png # 需要在public文件夹下存放该文件名的图片,否则不显示图片
heroText: Hero 标题 # 如果不需要可以设置为mull
tagline: Hero 副标题 # 如果不需要可以设置为mull
actionText: 快速上手 
actionLink: /zh/guide/
features:
- title: 简洁至上
  details:  Markdown 为中心的项目结构,以最少的配置帮助你专注于写作。
- title: Vue驱动
  details: 享受 Vue + webpack 的开发体验,在 Markdown 中使用 Vue 组件,同时可以使用 Vue 来开发自定义主题。
- title: 高性能
  details: VuePress 为每个页面预渲染生成静态的 HTML,同时在页面被加载的时候,将作为 SPA 运行。
footer: MIT Licensed | Copyright © 2018-present Evan You
---

重新运行一下项目,可以看到下面的效果:

image-20200711151425246

这样看上去,是不是就有博客的样子了。

4.2 导航栏

导航栏的配置包括下面的几项,可以根据自己的需要进行配置,配置文件在.vuepress/config.js

  • 页面标题
  • 搜索框
  • 导航栏链接
  • 多语言切换
  • 仓库链接
module.exports = {
  themeConfig: {
    // navbar: false, // 禁用导航栏
    logo: '/assets/img/logo.png', // 配置导航Log
    nav: [ //配置导航链接
      {text: 'Home', link: '/'},
      {text: 'Guide', link: '/guide/'},
      {text: 'External', link: 'https://google.com'},
      /* 外部链接可以配置target和rel */
      {text: 'External', link: 'https://google.com', target: '_self', rel: ''},
      {text: 'Guide', link: '/guide/', target: '_blank'},
      {
        text: 'Languages',
        ariaLabel: 'Language Menu',
        items: [ // 如果提供了一个items,会用下拉框的形式显示
          {text: 'Chinese', link: '/language/chinese/'},
          {text: 'Japanese', items: [/*  */]} //还可以进行嵌套items
        ]
      }
    ]
  }
};

重新运行一下看效果:

image-20200711152834391

4.3 侧边栏

module.exports = {
  themeConfig: {
    sidebar: 'auto' // 自动生成侧边栏
  }
};

image-20200711155130504

但是在这里我发现了一个问题,一篇文章中只能存在一个一级标题,因为自动生成的侧边栏貌似只会生成一个一级标题。

侧边栏的更多配置可以参考官方文档,如果有需要的话根据文档进行配置。

5. 在Markdown中使用Vue

为什么要使用VuePress创建博客呢,因为它可以在Markdown中使用Vue,这就极大的提高了界面的自定义,但是它有着浏览器API访问限制,因为所有的页面在生成静态 HTML 时都需要通过Node.js服务端渲染,所以请确保只在beforeMount或者mounted访问浏览器 / DOMAPI

5.1 插值

每一个 Markdown 文件将首先被编译成 HTML,接着作为一个 Vue 组件传入 vue-loader,这意味着你可以在文本中使用 Vue 风格的插值:

Input

{{ 1 + 1 }}

Output

2

5.2 指令

同样地,也可以使用指令:

Input

<span v-for="i in 3">{{ i }} </span>

Output

1 2 3

5.3 访问网站以及页面的数据

编译后的组件没有私有数据,但可以访问 网站的元数据,举例来说:

Input

{{ $page }}

Output

{
  "path": "/using-vue.html",
  "title": "Using Vue in Markdown",
  "frontmatter": {}
}

5.4 转义

默认情况下,块级 (block) 的代码块将会被自动包裹在 v-pre 中。如果你想要在内联 (inline) 的代码块或者普通文本中显示原始的大括号,或者一些 Vue 特定的语法,你需要使用自定义容器 v-pre 来包裹:

Input

::: v-pre
`{{ This will be displayed as-is }}`
:::

Output

{{ This will be displayed as-is }}

5.5 使用组件

所有在 .vuepress/components 中找到的 *.vue 文件将会自动地被注册为全局的异步组件。

你可以直接使用这些组件在任意的 Markdown 文件中(组件名是通过文件名取到的):

<demo-1/>
<OtherComponent/>
<Foo-Bar/>

5.6 使用预处理器

vue中已经内置了 stylusstylus-loader,所以不需要再安装它们,而sassscsslessstyluspug。要使用它们你只需要在项目中安装对应的依赖即可。例如,要使用 sass,需要安装:

yarn add -D sass-loader node-sass

然后你就可以在 Markdown 或是组件中使用如下代码:

<style lang="sass">
  .title
    font-size: 20px
</style>

要在组件中使用 <template lang="pug">,则需要安装 pugpug-plain-loader:

yarn add -D pug pug-plain-loader

6. 其它配置

6.1 内部链接

网站内部的链接,将会被转换成 <router-link> 用于 SPA 导航。同时,站内的每一个文件夹下的 README.md 或者 index.md 文件都会被自动编译为 index.html,对应的链接将被视为 /

以如下的文件结构为例:

.
├─ README.md
├─ foo
│  ├─ README.md
│  ├─ one.md
│  └─ two.md
└─ bar
   ├─ README.md
   ├─ three.md
   └─ four.md

假设你现在在 foo/one.md 中:

[Home](/) <!-- 跳转到根部的 README.md -->
[foo](/foo/) <!-- 跳转到 foo 文件夹的 index.html -->
[foo heading](./#heading) <!-- 跳转到 foo/index.html 的特定标题位置 -->
[bar - three](../bar/three.md) <!-- 具体文件可以使用 .md 结尾(推荐) -->
[bar - four](../bar/four.html) <!-- 也可以用 .html -->

6.2 Emoji

输入

:tada: :100:

输出

🎉 💯

所有可用的Emoji

6.3 行号

可以通过配置来为每个代码块显示行号:

module.exports = {
  markdown: {
    lineNumbers: true
  }
}

7. 部署

项目的部署是十分简单的,直接运行

npm run docs:build

进入到docs\.vuepress\dist就可以看到打包后的静态文件,你可以将它们发布到GitHub Pages或者你自己的服务器上面。

8. 总结

VuePressHexo各有各的优点,因为Hexo出来的时间很久了所以技术上也相对成熟,主题也相对较多,但是缺点是使用了EJS,虽然让使用者更加方便,但是对于DIY来讲要额外进行学习。

VuePress就可以直接使用Vue这个前端几乎必修的框架,DIY就显得非常方便,但是因为出来的时间短,主题也相对较少。所以如果对于不了解前端技术的同学,还是推荐使用Hexo