VuePress 入门教程之一基础篇

前言

版本说明

本文的内容是基于 VuePress 1.x 讲解的,一切内容以 官方文档 为准。

教程大纲

静态网站生成器比较

Hexo

Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其它渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。Hexo 配合它的主题模块,比如 NexT 主题,可以作为非常简洁方便的静态博客系统。

GitBook

GitBook 是一个现代的文档平台,团队或个人可以在其上编写产品、API 接口文档以及团队内部知识库。GitBook 改版之后,感觉团队更专注于商业产品而不是开源工具,同时 CLI 工具不再提供了,所以无法实现个性化部署。

Nuxt

Nuxt.js 是一个基于 Vue.js 的通用应用框架。通过对客户端 / 服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI 渲染。Nuxt.js 的目标是创建一个灵活的应用框架,你可以基于它初始化新项目的基础结构代码,或者在已有 Node.js 项目中使用 Nuxt.js。简而言之,Nuxt.js 更像是为构建应用程序而生的,而不是独立的内容静态网站。

Docsify

Docsify 是一个动态生成文档网站的工具。不同于 GitBook、Hexo 的地方是它不会生成将 .md 转成 .html 文件,所有转换工作都是在运行时进。Docsify 是基于 Vue,完全的运行时驱动,不需要渲染 HTML,所以对 SEO 不够友好。如果不关注 SEO,安装简单化不想有大量依赖,它是比较好的选择,比如公司或这团队内部的文档系统。

Docute

Docute 本质上就是一个 JavaScript 文件,它可以获取 Markdown 文件并将它们呈现为单页面应用。它完全由运行时驱动,因此并不涉及服务端组件,这就意味着没有构建过程。你只需创建一个 HTML 文件和一堆 Markdown 文档,你的网站就差不多完成了!Docute 与 Docsify 基本一样,只是在文件大小和 UI 及不同的使用方式,Docute 官网有其差异的介绍。

VuePress

VuePress 实际上是由 Vue、Vue Router 和 Webpack 驱动的单页面应用程序,实现了 GitBook 的功能。VuePress 展示页面与 Docsify 类似,但是与 Docsify 不同的是会预先渲染 HTML。每个 Markdown 文件都使用 markdown-it 编译为 HTML,然后作为 Vue 组件的模板进行处理;这允许你直接在 Markdown 文件中使用 Vue,在需要嵌入动态内容时,这种使用方式非常有用。

Other

Jekyll、Typecho、Hugo、Ghost

VuePress 介绍

VuePress 由两部分组成:第一部分是一个极简静态网站生成器,它包含由 Vue 驱动的主题系统插件 API,另一个部分是为书写技术文档而优化的默认主题,它的诞生初衷是为了支持 Vue 及其子项目的文档需求。每一个由 VuePress 生成的页面都带有预渲染好的 HTML,也因此具有非常好的加载性能和搜索引擎优化(SEO)。同时,一旦页面被加载,Vue 将接管这些静态内容,并将其转换成一个完整的单页应用(SPA),其他的页面则会只在用户浏览到的时候才按需加载。

工作原理

事实上,一个 VuePress 网站是一个由 VueVue RouterWebpack 驱动的单页应用。如果你以前使用过 Vue 的话,当你在开发一个自定义主题的时候,你会感受到非常熟悉的开发体验,你甚至可以使用 Vue DevTools 去调试你的自定义主题。在构建时,我们会为应用创建一个服务端渲染(SSR)的版本,然后通过虚拟访问每一条路径来渲染对应的 HTML。这种做法的灵感来源于 Nuxtnuxt generate 命令,以及其他的一些项目,比如 Gatsby

功能说明

内置的 Markdown 拓展

在 Markdown 中 使用 Vue

Vue 驱动的自定义主题系统

默认主题

博客主题

Plugin

VuePress 快速入门

Warning 前提条件:VuePress 需要 Node.js >= 8.6

下述内容会帮助你从头搭建一个简单的 VuePress 文档,如果你想在一个现有的项目中使用 VuePress 来管理文档,从步骤 3 开始。

  1. 创建并进入一个新目录
1
$ mkdir vuepress-starter && cd vuepress-starter
  1. 使用你喜欢的包管理器进行初始化
1
2
3
4
$ yarn init

# 或者
$ npm init
  1. 将 VuePress 安装为本地依赖
1
2
3
4
$ yarn add -D vuepress

# 或者
$ npm install -D vuepress # npm install vuepress --save-dev

Warning 注意:官方已经不再推荐全局安装 VuePress,如果你的现有项目依赖了 Webpack 3.x,则推荐使用 Yarn 而不是 NPM 来安装 VuePress。因为在这种情形下,NPM 会生成错误的依赖树

  1. 创建第一篇文档
1
$ mkdir docs && echo '# Hello VuePress' > docs/README.md
  1. package.json 中添加一些 scripts

这一步骤是可选的,但推荐你完成它。在下文中,会默认这些 scripts 已经被添加。

1
2
3
4
5
6
{
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
}
}
  1. 在本地启动服务器
1
2
3
4
$ yarn docs:dev

# 或者
$ npm run docs:dev

VuePress 会在 http://127.0.0.1:8080 启动一个热重载的开发服务器,此时你就拥有了一个简单可用的 VuePress 文档。当你的文档逐渐成型的时候,不要忘记 VuePress 的 多语言支持 ,并了解一下如何将你的文档 部署 到任意静态文件服务器上。

  1. 目录结构说明

如果 docs 目录做为顶级目录(非 vuepress-starter 的子目录),如下所示:

1
2
3
4
5
6
.
├─ docs
│ ├─ README.md
│ └─ .vuepress
│ └─ config.js
└─ package.json

那么 package.json 的配置内容需要更改为:

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

Shell 脚本的内容则更改为:

1
2
3
4
$ yarn dev

# 或者
$ npm run dev

VuePress 基础概念

目录结构

VuePress 遵循 “约定优于配置” 的原则,推荐的目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.
├── 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

Warning 注意:请留意目录名的大写

  • 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: 客户端应用的增强。

Warning 注意:当你想要去自定义 templates/ssr.htmltemplates/dev.html 时,最好基于 默认的模板文件 来修改,否则可能会导致构建出错

页面路由

此处一般把 docs 目录作为 targetDir (参考 命令行接口),下面所有的 “文件的相对路径” 都是相对于 docs 目录的。在项目根目录下的 package.json 中添加如下 scripts

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

对于上述的目录结构,Vuepress 的默认页面路由地址如下:

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

基本配置

配置文件

如果没有任何配置,这个网站将会是非常局限的,用户也无法在你的网站上自由导航。为了更好地自定义你的网站,首先需要在你的文档目录下创建一个 .vuepress 目录,所有 VuePress 相关的文件都将会被放在这里,项目结构示例如下:

1
2
3
4
5
6
.
├─ docs
│ ├─ README.md
│ └─ .vuepress
│ └─ config.js
└─ package.json

一个 VuePress 网站最必要的配置文件是 .vuepress/config.js,它应该导出一个 JavaScript 对象:

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

对于上述的配置,如果你运行起 dev server,你应该能看到一个页面,它包含一个页头,里面包含一个标题和一个搜索框。VuePress 内置了基于 headers 的搜索 —— 它会自动为所有页面的标题、h2h3 构建起一个简单的搜索索引。可参见 配置 来查看所有可配置的选项。

Tip 其他配置格式:你也可以使用 YAML (.vuepress/config.yml) 或是 TOML (.vuepress/config.toml) 格式的配置文件

主题配置

一个 VuePress 主题应该负责整个网站的布局和交互细节。在 VuePress 中,目前自带了一个默认的主题(正是你现在所看到的),它是为技术文档而设计的。同时,默认主题提供了一些选项,让你可以去自定义导航栏(navbar)、 侧边栏(sidebar)和 首页(homepage) 等,详情请参见 默认主题配置 ,如果你想开发一个自定义主题,可以参考 自定义主题

应用级别的配置

由于 VuePress 是一个标准的 Vue 应用,你可以通过创建一个 .vuepress/enhanceApp.js 文件来做一些应用级别的配置,当该文件存在的时候,会被导入到应用内部。enhanceApp.js 应该 export default 一个钩子函数,并接受一个包含了一些应用级别属性的对象作为参数。你可以使用这个钩子来安装一些附加的 Vue 插件、注册全局组件,或者增加额外的路由钩子等:

1
2
3
4
5
6
7
8
9
10
// 使用异步函数也是可以的
export default ({
Vue, // VuePress 正在使用的 Vue 构造函数
options, // 附加到根实例的一些选项
router, // 当前应用的路由实例
siteData, // 站点元数据
isServer // 当前应用配置是处于 服务端渲染 或 客户端
}) => {
// ...做一些其他的应用级别的优化
}

静态资源

相对路径

所有的 Markdown 文件都会被 Webpack 编译成 Vue 组件,因此你可以,并且应该更倾向于使用相对路径(Relative URLs)来引用所有的静态资源:

1
![An image](./image.png)

同样地,这在 *.vue 文件的模板中一样可以工作,图片将会被 url-loaderfile-loader 处理,在运行生成静态文件的构建任务时,文件会被复制到正确的位置。


除此之外,你也使用 ~ 前缀来明确地指出这是一个 Webpack 的模块请求,这将允许你通过 Webpack 别名来引用文件或者 NPM 的依赖:

1
2
![Image from alias](~@alias/image.png)
![Image from dependency](~some-dependency/image.png)

Webpack 的别名可以通过 .vuepress/config.jsconfigureWebpack 来配置,如:

1
2
3
4
5
6
7
8
9
module.exports = {
configureWebpack: {
resolve: {
alias: {
'@alias': 'path/to/some/dir'
}
}
}
}

公共文件

有时,你可能需要提供一个静态资源,但是它们并不直接被你的任何一个 Markdown 文件或者主题组件引用 —— 举例来说,favicons 和 PWA 的图标,在这种情形下,你可以将它们放在 .vuepress/public 中, 它们最终会被复制到生成的静态文件夹中。

基础路径

如果你的网站会被部署到一个非根路径,你将需要在 .vuepress/config.js 中设置 base,举例来说,如果你打算将你的网站部署到 https://foo.github.io/bar/,那么 base 的值就应该被设置为 "/bar/" (应当总是以斜杠开始,并以斜杠结束)。有了基础路径(Base URL),如果你希望引用一张放在 .vuepress/public 中的图片,你需要使用这样路径:/bar/image.png,然而,一旦某一天你决定去修改 base,这样的路径引用将会显得异常脆弱。为了解决这个问题,VuePress 提供了内置的一个 helper $withBase(它被注入到了 Vue 的原型上),可以帮助你生成正确的路径:

1
<img :src="$withBase('/foo.png')" alt="foo">

值得一提的是,你不仅可以在你的 Vue 组件中使用上述的语法,在 Markdown 文件中亦是如此。最后补充一句,一个 base 路径一旦被设置,它将会自动地作为前缀插入到 .vuepress/config.js 中所有以 / 开始的资源路径中。

多语言支持

站点多语言配置

要启用 VuePress 的多语言支持,首先需要使用如下的文件结构:

1
2
3
4
5
6
7
8
9
10
docs
├─ README.md
├─ foo.md
├─ nested
│  └─ README.md
└─ zh
├─ README.md
├─ foo.md
└─ nested
   └─ README.md

然后,在 .vuepress/config.js 中提供 locales 选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = {
locales: {
// 键名是该语言所属的子路径
// 作为特例,默认语言可以使用 '/' 作为其路径。
'/': {
lang: 'en-US', // 将会被设置为 <html> 的 lang 属性
title: 'VuePress',
description: 'Vue-powered Static Site Generator'
},
'/zh/': {
lang: 'zh-CN',
title: 'VuePress',
description: 'Vue 驱动的静态网站生成器'
}
}
}

如果一个语言没有声明 title 或者 description,VuePress 将会尝试使用配置顶层的对应值。如果每个语言都声明了 titledescription,则顶层的这两个值可以被省略。

默认主题多语言配置

默认主题也内置了多语言支持,可以通过 themeConfig.locales 来配置。该选项接受同样的 { path: config } 格式的值。每个语言除了可以配置一些站点中用到的文字之外,还可以拥有自己的 导航栏侧边栏 配置:

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
module.exports = {
locales: {
'/': {
lang: 'en-US',
title: 'VuePress',
description: 'Vue-powered Static Site Generator'
},
'/zh/': {
lang: 'zh-CN',
title: 'VuePress',
description: 'Vue 驱动的静态网站生成器'
}
},
themeConfig: {
locales: {
'/': {
selectText: 'Languages',
label: 'English',
ariaLabel: 'Languages',
editLinkText: 'Edit this page on GitHub',
algolia: {},
nav: [
{text: 'Nested', link: '/nested/', ariaLabel: 'Nested'}
],
sidebar: {
'/nested/': [/* ... */]
}
},
'/zh/': {
// 多语言下拉菜单的标题
selectText: '选择语言',
// 该语言在下拉菜单中的标签
label: '简体中文',
// 编辑链接文字
editLinkText: '在 GitHub 上编辑此页',
// 当前 locale 的 algolia docsearch 选项
algolia: {},
nav: [
{text: '嵌套', link: '/zh/nested/'}
],
sidebar: {
'/zh/nested/': [/* ... */]
}
}
}
}
}

编译构建

  1. config.js 中指定构建的目标目录:
1
2
3
module.exports = {
dest: 'docs/.vuepress/dist'
}
  1. 通过以下命令编译构建,生成 VuePress 网站所需的静态文件,这样就可以很方便地将 VuePress 文档部署到任意的 Web 服务器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 编译构建
$ yarm docs:build

# 或者
$ npm run docs:build

# 成功编译后,会在指定的目录下生成网站的所有静态文件,目录结构如下
docs/.vuepress/dist
├── 404.html
├── assets
├── contact
├── debug
├── en
├── faq
├── favicon.ico
├── guide
├── hero.png
├── index.html
├── logo.png
├── manifest.json
└── service-worker.js
  1. 目录结构说明

如果 docs 目录做为顶级目录,如下所示:

1
2
3
4
5
6
.
├─ docs
│ ├─ README.md
│ └─ .vuepress
│ └─ config.js
└─ package.json

那么 config.js 的配置内容需要更改为:

1
2
3
module.exports = {
dest: '.vuepress/dist'
}

编译构建的命令则更改为:

1
2
3
4
$ yarn build

# 或者
$ npm run build

部署方式

GitHub Pages

  1. docs/.vuepress/config.js 中设置正确的 base
  • 如果你打算发布到 https://<USERNAME>.github.io/,则可以省略这一步,因为 base 默认即是 "/"
  • 如果你打算发布到 https://<USERNAME>.github.io/<REPO>/(也就是说你的仓库在 https://github.com/<USERNAME>/<REPO>),则将 base 设置为 "/<REPO>/"
  1. 在你的项目中,创建一个如下的 deploy.sh 文件(请自行判断去掉对应的注释)
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
#!/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 -

你可以在你的持续集成的设置中,设置在每次 Push 代码时自动运行上述 Shell 脚本

GitHub Pages and Travis CI

  1. docs/.vuepress/config.js 中设置正确的 base
  • 如果你打算发布到 https://<USERNAME or GROUP>.github.io/,则可以省略这一步,因为 base 默认即是 "/"
  • 如果你打算发布到 https://<USERNAME or GROUP>.github.io/<REPO>/(也就是说你的仓库在 https://github.com/<USERNAME>/<REPO>),则将 base 设置为 "/<REPO>/"
  1. 在项目的根目录创建一个名为 .travis.yml 的文件

  2. 在本地执行 yarnnpm install 并且提交生成的 lock 文件(即 yarn.lockpackage-lock.json

  3. 使用 GitHub Pages 部署提供程序模板,并遵循 Travis 文档规范 来编写 .travis.yml 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
language: node_js
node_js:
- lts/*
install:
- yarn install # npm ci
script:
- yarn docs:build # npm run docs:build
deploy:
provider: pages
skip_cleanup: true
local_dir: docs/.vuepress/dist
github_token: $GITHUB_TOKEN # 在 GitHub 中生成,用于允许 Travis 向你的仓库推送代码。在 Travis 的项目设置页面进行配置,设置为 secure variable
keep_history: true
on:
branch: master