静的サイトジェネレータ「VuePress」の導入からデフォルトテーマの簡単な設定までを紹介します。
Node.jsがインストール済みで少しコマンドが入力できさえすれば、Vueの知識がなくてもそれっぽいドキュメントがすぐ作れるような形で紹介しているので、興味ある方は試してみてください。

  • Node.js(Ver 8以上)が必要になるので、使っている覚えのない方や使用しているバージョンが古い方は、Node.jsをインストールまたはアップデートをしてください。
    コマンドで$ node -vを入力すれば、インストールの有無やバージョン確認ができます。
  • 「Getting Started」ではYarnとnpmそれぞれのコマンドで紹介しますが、それ以降は基本的にYarnを用いた形で紹介しているので、npmを利用している場合は置き換えてください。
  • 紹介している内容は、VuePress Ver 0.14.8を使用した場合になります。

VuePressとは

VuePress」とは、Vue.jsの作者であるEvan You氏が作成した静的サイトジェネレータです。
わかりやすい特徴としては、Markdownで書かれたファイルをhtmlとして生成することができ、さらにMarkdown内でVueが使用可能になっていたり、Vueを使ったカスタムテーマ開発ができます。
また、デフォルトで用意されたテーマは技術文書を書くために最適化されたものになっているので、ちょっとしたドキュメント作成が容易に行えます。

その他の特徴やより具体的にVuePressについて知りたい場合は、以下公式サイトで確認できます。

Getting Started

導入

まずは開発用のディレクトリを作成して、$ cdでカレントディレクトリを移動します。
今回はhello-vuepressというディレクトリ名で作成する想定なので、その他のディレクトリ名の場合は下記コマンド内のhello-vuepressの部分を任意で変更してください。

$ mkdir hello-vuepress
$ cd hello-vuepress

移動後、package.jsonの作成(場合によってはスルー)とVuePressのインストールを行います。
package.jsonは各項目を任意で設定したければ-yを省いて実行し、VuePressについてはローカルにインストールしていきます。

Yarn
# create package.json
$ yarn init -y

# install VuePress
$ yarn add -D vuepress
npm
# create package.json
$ npm init -y

# install VuePress
$ npm i -D vuepress

この時点で開発用ディレクトリの中身はそれぞれ下記のような構成になっていると思います。

開発用ディレクトリのファイル構成 (Yarn)
/hello-vuepress
 ├─ /node_modules
 ├─ package.json
 └─ yarn.lock
開発用ディレクトリのファイル構成 (npm)
/hello-vuepress
 ├─ /node_modules
 ├─ package.json
 └─ package-lock.json

次にトップページとして表示させるMarkdown(マークダウン)ファイルを作成します。
開発用ディレクトリ内にsrcというディレクトリを作成し、さらにその中にindex.mdというファイルを作成します。
index.md内の記述は任意で構いませんが、ここでは# Hello VuePressと記述されたものを作成し、コマンドで行う場合は下記を実行します。

$ mkdir src
$ echo '# Hello VuePress' > src/index.md
/hello-vuepress/src/index.md
# Hello VuePress

公式のチュートリアルだとドキュメントサポートとして作成されたこともあって、docsディレクトリを作成し、ディレクトリ内にはREADME.mdファイルを作成(README.mdindex.htmlに変換してくれるため)とありますが、特にドキュメント以外の用途なども考えるとこちらの方がわかりやすのではないかと個人的に思うので、ここではsrcindex.mdで説明しています。

今回はVuePressをローカルインストールしているので、最後に実行するためのコマンドをpackage.jsonscripts部分に下記を追記していきます。(package.json内にscriptsが見当たらない場合は追加してください。)
"dev": "vuepress dev src"は開発時、"build": "vuepress build src"はビルド時に使用するものになり、それぞれ末尾にあるsrcという部分は上でindex.mdを配置したディレクトリ名を指定します。

package.json
{
  "scripts": {
    "dev": "vuepress dev src",
    "build": "vuepress build src"
  }
}

ここで紹介している方法を上から順に行なっているのであれば、package.jsonは下記いずれかのような記述になっていると思います。

package.json (Yarn)
{
  "name": "hello-vuepress",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "vuepress": "^0.14.8"
  },
  "scripts": {
    "dev": "vuepress dev src",
    "build": "vuepress build src"
  }
}
package.json (npm)
{
  "name": "hello-vuepress",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "vuepress dev src",
    "build": "vuepress build src"
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "vuepress": "^0.14.8"
  }
}

表示確認

導入作業後の表示確認時のイメージ

紹介してきた導入の流れがひと通り完了したら、下記コマンドで表示確認が可能になります。
実行後、しばらくするとコマンド内にVuePress dev server listening at http://localhost:8080/と表示されると思うので、http://localhost:8080/にアクセスすればイメージのように表示されるのを確認できます。

Yarn
$ yarn dev
npm
$ npm run dev

ちなみに、この状態のまま先ほどのindex.mdの中身を変更するとブラウザ側の表示にその内容が即反映されると思うので、記述したMarkdownが実際にどのように表示されるかを容易に確認することができます。
また、確認終了時はコマンドにWinならCtrl + c、Macならcommand + cを入力します。

ビルド

ビルドは下記コマンドを実行します。
問題なければ/hello-vuepress/docs/.vuepress/dist内にindex.html/assetsといったファイルが生成されているのを確認できます。

Yarn
$ yarn build
npm
$ npm run build

デフォルトのMarkdown拡張やスタイル

様々な用途で使うのであればカスタムして利用することが多くなるとは思いますが、ドキュメントサポート向けに作られたこともあって、デフォルトでも下記のように便利なMarkdown拡張やそれっぽい見た目にしてくれるスタイルがひと通り用意されています。

ヘッダーアンカーと目次生成

ヘッダーアンカーと目次生成後のイメージ

見出し(#######)を記述すると自動的にアンカーリンクを設定してくれます。
また、表示させたい箇所に[[toc]]と記述することで、デフォルトだとページ内の#####から生成した目次を簡単に追加することができます。

[[toc]]

## タイトル 1

### サブタイトル 1-1

### サブタイトル 1-2

## タイトル 2

GitHubスタイルのテーブル

GitHubスタイルのテーブル表示イメージ

|, -, :を組み合わせればテーブル(表)を作成できます。
見た目はゼブラストライプを採用しているGitHubスタイルのものになります。

| left col     | center col   | right col    |
| ------------ |:------------:| ------------:|
| foo          | bar          | baz          |
| qux          | quux         | corge        |
| grault       | garply       | waldo        |

シンタックスハイライト

シンタックスハイライト適用後のイメージ

コードの前後に```を記述することでコードブロックとして表示させることができ、さらに最初の```記述後に言語を指定することでより見やすい形で表示してくれます。
また、言語指定後に{行数}を記述することで特定の行をハイライトさせることも可能で、例えば下記は言語がJavaScriptで4行目をハイライト表示させたい場合になります。

``` js{4}
export default {
  data () {
    return {
      msg: 'Highlighted!'
    }
  }
}
```

ハイライト表示を複数行指定したい場合は、例えば2行目と4行目のように離れているならば,区切りで{2,4}と指定し、2〜4行目までのようにまとめて指定するなら-を用いて{2-4}と記述します。

カスタムコンテナ

各種カスタムコンテナのイメージ

ちょっとしたヒントや警告を表示させたいとき用のスタイルとしてカスタムコンテナというものが用意されており、任意の文章を:::で括り、最初の:::記述後に「tip」「warning」「danger」のいずれかを記述することで表示を変えることができます。
また、デフォルトではタイトルとして「TIP」または「WARNING」が表示されますが、下記サンプルの一番下のようにタイプ指定後に文字列を記述することで任意のタイトルで表示できます。

::: tip
This is a tip
:::

::: warning
This is a warning
:::

::: danger
This is a dangerous warning
:::

::: tip VuePress
Vue-powered Static Site Generator
:::

ここで紹介しているのも用意されている中の一部で、他にもmarkdown-itで対応している絵文字が使えたり、リンク指定も内部・外部ともにできます。
このようにちょっとしたドキュメントを作る際に使えそうな機能や見た目がデフォルトで用意されているので、簡易的なドキュメントであれば環境を用意してMarkdownを少し書くだけで簡単に作成できると思います。

ページを追加

VuePressはmdファイルをhtmlファイルに変換してくれるので、ページを追加したい場合もトップページを作成したときと同様で新しいMarkdownを追加するだけで作成できます。
ここでは例としてindex.mdと同じディレクトリ内にAboutページを作成する想定で、「# About page」と記述されたindex.mdというファイルを作成します。

$ echo '# About page' > src/about.md
作成後のファイル構成
/src
 ├─ index.md
 └─ about.md

作成後、$ yarn devを実行してhttp://localhost:8080/about.htmlにアクセスすれば、新たに作成したAboutページが確認できます。

ファイルではなくディレクトリとして/aboutを用意してhttp://localhost:8080/about/のようなURLで表示したい場合は、下記のようにindex.mdを含めたディレクトリを作成します。

$ mkdir src/about
$ echo '# About directory page' > src/about/index.md
作成後のファイル構成
/src
 ├─ index.md
 └─ /about
      └─ index.md

作成後、$ yarn devを実行してhttp://localhost:8080/about/にアクセスすれば、Aboutディレクトリ内のページとして確認できます。

ナビゲーションを追加

ナビゲーションの表示イメージ

ページが複数存在する場合に必要になってくるのがナビゲーションです。
特にカスタマイズをしていないデフォルトの状態だとヘッダー内には右上に検索エリアが表示されているだけだと思いますが、その横に各ページに移動できるナビゲーションを追加してみます。

ナビゲーションは/.vuepress内のconfig.jsに必要な記述をすることで追加することができ、後ほどいくつか紹介しますが、VuePressやテーマの設定を変更する際は主にこのファイルに記述していきます。
該当ファイルが見当たらない場合は、/src/.vuepress内にconfig.jsを作成してください。

$ touch src/.vuepress/config.js

ナビゲーションの追加はconfig.jsに下記のように記述します。

config.js
module.exports = {
  themeConfig: {
    nav: [
      { text: 'Home', link: '/' },
      { text: 'About', link: '/about/' },
      { text: 'Blog', link: 'https://www.nxworld.net/' }
    ]
  }
}

textで表示させるテキスト、linkで該当ページへのパスやURLといったリンク先をそれぞれ指定し、問題なく実装できれば検索エリア横に表示されます。
現在見ているページにはカレントを示す下線が付き、サンプルコードにある「Blog」のようにlinkを絶対パスで指定すると外部リンクを示すアイコンが付与されます。

ドロップダウンメニューを使う

ページ数が増えてきたなどの理由でナビゲーション周りをもう少しスッキリさせたいときは、ドロップダウンメニューを使うこともできます。
ドロップダウンメニューはlinkの代わりにitemsを使用し、上で実装したものをそのままひとつのドロップダウンメニューとして表示する場合は、config.jsに下記のように記述します。

config.js
module.exports = {
  themeConfig: {
    nav: [
      {
        text: 'Nav',
        items: [
          { text: 'Home', link: '/' },
          { text: 'About', link: '/about/' },
          { text: 'Blog', link: 'https://www.nxworld.net/' }
        ]
      }
    ]
  }
}

また、テキストリンクとドロップダウンメニューを一緒に使うことも可能です。
config.jsに下記のように記述すると「Home」「About」「Blog」はそのままリンクとして表示され、「More」のみがドロップダウンメニューとして表示されます。

config.js
module.exports = {
  themeConfig: {
    nav: [
      { text: 'Home', link: '/' },
      { text: 'About', link: '/about/' },
      { text: 'Blog', link: 'https://www.nxworld.net/' },
      {
        text: 'More',
        items: [
          { text: 'Twitter', link: 'https://twitter.com/' },
          { text: 'GitHub', link: 'https://github.com/' },
          { text: 'Dribbble', link: 'https://dribbble.com/' }
        ]
      }
    ]
  }
}

サイドバーを追加

サイドバーの表示イメージ

ヘッダーのナビゲーションだけでなく、イメージのようなサイドバーも追加することができます。
どのように追加するかにもよりますが、サイドバーの場合は主に各ページへのナビゲーションや見出しを用いた目次が表示され、追加するにはconfig.jsに下記のように記述します。

config.js
module.exports = {
  themeConfig: {
    sidebar: [
      '/',
      '/about/'
    ]
  }
}

ナビゲーションとは違って、サイドバーはページへのパスを指定すればテキストを自動で表示してくれます。
テキストを任意で指定したい場合は[link, text]と記述し、例えば上のサンプルコードで'/about/'となっているところを['/about/', 'About VuePress']に変更すれば、サイドバーに/aboutへのリンクが「About VuePress」というテキストで表示されます。

ページ内の目次として使用する

themeConfig.sidebar'auto'と指定すれば、他ページへのリンクは表示せずに現在見ているページの目次表示のみ表示する形になります。

config.js
module.exports = {
  themeConfig: {
    sidebar: 'auto'
  }
}

ヘッダーリンク表示の設定

サイドバーではそれぞれリンク付きページタイトル下にh2##)から生成されたヘッダーリンクがネスト表示されるのですが、これはthemeConfig.sidebarDepthで表示階層を設定できます。

config.js
module.exports = {
  themeConfig: {
    sidebar: [
      '/',
      '/about/'
    ],
    sidebarDepth: 2
  }
}

デフォルトではh2##)のみを対象とした目次が表示されますが、上記のように記述することでh3###)も含めた形で表示されます。
また、sidebarDepth: 0の指定でヘッダーリンクは表示されずページタイトルのみが表示されます。

全ページで目次を表示

デフォルトでは現在見ているページの目次(ヘッダーリンク)のみサイドバーに表示されますが、themeConfig.displayAllHeaderstrueにすることで全ページで常に表示させることができます。

config.js
module.exports = {
  themeConfig: {
    sidebar: [
      '/',
      '/about/'
    ],
    displayAllHeaders: true
  }
}

ヘッダーリンクのカレント表示とハッシュ付与の設定

デフォルトでは現在見ているページタイトルをカレント表示してくれるだけでなく、ページ内をスクロールした際の表示セクションによってヘッダーリンクにカレント表示を付けたりURLにハッシュが付与されます。
これらが不要な場合はthemeConfig.activeHeaderLinksfalseにします。

config.js
module.exports = {
  themeConfig: {
    sidebar: [
      '/',
      '/about/'
    ],
    activeHeaderLinks: false
  }
}

各種設定

ナビゲーションの追加方法を紹介する際に少し触れましたが、VuePressやテーマの設定を変更する場合はconfig.jsに記述していきます。
これまで紹介している内容を上から順に辿っていればすでに配置されていると思いますが、該当ファイルが見当たらない場合は、/src/.vuepress内にconfig.jsを作成してください。

$ touch src/.vuepress/config.js

主な設定項目としては、以下のようなものがあります。

  • title
    サイトタイトルを設定するもので、指定すればhead内のtitleにも反映される他、ヘッダーにもサイトタイトルとして表示されます。

    config.js
    module.exports = {
      title: 'example title'
    }
  • description
    head内のmeta descriptionを設定できます。

    config.js
    module.exports = {
      description: 'example description'
    }
  • head
    head内に新しくタグを追加することができます。
    [tagName, { attrName: attrValue }, innerHTML?]のようにタグや属性などを指定でき、例えば下記のように記述することでファビコンと各種OGPタグを追加できます。

    config.js
    module.exports = {
      head: [
        ['link', { rel: 'icon', type: 'image/png', href: '/favicon.png' }],
        ['meta', { name: 'og:url', content: 'https://example.com/' }],
        ['meta', { name: 'og:type', content: 'website' }],
        ['meta', { name: 'og:title', content: 'example title' }],
        ['meta', { name: 'og:description', content: 'example description' }],
        ['meta', { name: 'og:image', content: '/og.png' }]
      ]
    }
  • dest
    デフォルトではビルド時に/.vuepress/distにファイルが生成されるのを任意の場所に変更でき、下記の場合は開発環境のルートに/releaseという名前でディレクトリが生成されるようになります。

    config.js
    module.exports = {
      dest: 'release'
    }
  • locales
    利用することで言語によってタイトルなどを変えることができ、デフォルトだとen-USになっているlang属性をjaに変更する際にも利用します。

    config.js
    module.exports = {
      locales: {
        '/': {
          lang: 'ja'
        }
      }
    }

    言語によってタイトルを変える場合は、下記のような形で記述します。

    config.js
    module.exports = {
      locales: {
        '/': {
          lang: 'ja',
          title: 'VuePress入門'
        },
        '/en/': {
          lang: 'en-US',
          title: 'Hello VuePress'
        }
      }
    }

設定できる項目は他にも用意されており、以下でデフォルト値も含めて確認することができる他、テーマ・Markdown・ビルドパイプラインの設定などについても参照できます。

ページ毎に設定する

上でtitledescriptionを設定する方法を紹介しましたが、config.jsは全ページ共通の設定となるので、各ページで異なるものを設定する際はFront Matterを利用します。
Front Matterはページの先頭に---で括るような形で記述し、title, description, layout, meta, navbar, sidebarといった項目を指定できるようになっています。

例えばAとBというページがあり、共通設定としてdescriptionとサイドバー表示の指定がされているとします。
これをそれぞれ異なるOGP情報を表示させ、さらにAはサイドバーを非表示に、Bはdescriptionの内容を変更したい場合は、各ページの先頭に下記のように記述します。

page-a.md
---
sidebar: false
meta:
  - name: og:url
    content: https://example.com/page-a/
  - name: og:type
    content: website
  - name: og:title
    content: page-a title
  - name: og:description
    content: page-a description
  - name: og:image
    content: /og.png
---

# Page A
page-b.md
---
description: page-b description
meta:
  - name: og:url
    content: https://example.com/page-b/
  - name: og:type
    content: website
  - name: og:title
    content: page-b title
  - name: og:description
    content: page-b description
  - name: og:image
    content: /og.png
---

# Page B

その他設定できる項目については、以下でデフォルト値も含めて確認することができます。
また、JSONやTOMLでの記述もサポートしているので、慣れている人はFront Matterをそれらで記述することも可能です。

トップページのレイアウト変更

VuePressのデフォルトテーマには、シンプルなワンカラム表示だけでなくトップページ用として使えるレイアウトも用意されており、適用すればイメージのようにVuePressサイトのトップページのような見栄えを簡単に表示させることができます。

トップページのレイアウト変更後イメージ

トップページ用のレイアウトを適用するには、該当ページのFront Matterを下記のように記述します。

index.md
---
home: true
heroImage: /logo.png
actionText: About NxWorld
actionLink: /about/
features:
  - title: Simplicity First
    details: Minimal setup with markdown-centered project structure helps you focus on writing.
  - title: Vue-Powered
    details: Enjoy the dev experience of Vue + webpack, use Vue components in markdown, and develop custom themes with Vue.
  - title: Performant
    details: VuePress generates pre-rendered static HTML for each page, and runs as an SPA once a page is loaded.
footer: © 2018 NxWorld.
---

上記記述後、イメージ・titleとdescription(設定していれば)・3カラムレイアウトのコンテンツなどが表示されているのを確認できます。
それぞれの項目は下記のような内容を指定するものになっています。

  • home
    trueを指定することで、トップページ用のレイアウトが適用されます。
    homeの代わりにlayout: homeで指定するのでも可。)
  • heroImage
    イメージを表示させることができます。
    イメージを格納する際は/.vuepress内に/publicというディレクトリを作成し、その中に格納すればビルド時にもそのまま出力してくれます。
  • actionText / actionLink
    テキスト(actionText)とリンク先(actionLink)を指定すればボタンが表示されます。
  • features
    3カラムレイアウトのコンテンツを表示させることができ、記述時はtitledetailsをそれぞれ指定します。
  • footer
    ページ下部にフッターコンテンツが表示されます。

スタイル調整

もう少し自分好みに見栄えを調整したい場合は、/.vuepressoverride.stylを用意して記述していけば調整できます。
拡張子を見ての通りStylusになるので普通のCSS記法はもちろん、SASS記法やSCSS記法での記述も可能です。

$ touch src/.vuepress/override.styl

変数で指定

一部のスタイルに関しては変数で指定するだけで見栄えを変更できます。
例えば、デフォルトだとボタンの背景色やリンクの文字カラーなどがVueカラーのグリーンになっていますが、下記のように記述することでこれらを任意のカラーに指定することができます。

override.styl
$accentColor = #3498db

また、ヘッダーナビゲーションの高さを変更することもできます。

override.styl
$navbarHeight = 5rem

他にも下記のような変数が設定されているので、テキストカラー・コードブロックの背景カラー・コンテンツ幅などについてはわざわざ長々とスタイルを書かなくとも指定することが可能です。

// colors
$accentColor = #3eaf7c
$textColor = #2c3e50
$borderColor = #eaecef
$codeBgColor = #282c34
$arrowBgColor = #ccc

// layout
$navbarHeight = 3.6rem
$sidebarWidth = 20rem
$contentWidth = 740px

以上、かなり長くなってしまいましたが、VuePressの導入や簡易的な設定方法の紹介でした。
上でも何度か触れているように、ドキュメントサポート向けなのもあって環境を用意さえすればそれなりの見栄えで且つ容易に作成可能なので、取り急ぎドキュメントを用意したいときにも非常に便利だと思います。

今回はそこまで凝ったカスタマイズは紹介していませんが、オリジナルテーマを作成したりプラグインを使って機能を追加したりといったこともできるので、それらについても今後紹介できたらと思います。