Описание инструмента
VuePress представляет собой минималистичный генератор статичных сайтов, оптимизированный для написания технической документации.
Изначальной целью VuePress, была поддержка фреймворка Vue.js и сопутствующей инфраструктуры. Для примера, можно посмотреть любую документацию по Vue: Vue.js, Vue Router, Vuex, где применяется единый стиль, заложенный в основе VuePress.
В ходе статьи мы разберем архитектуру VuePress, разработаем базовое приложение и выложим на GitHub Pages.
Предварительная подготовка
1. Установка Node.js и NPM
Устанавливаем "Current" версию Node.js с официального сайта. При установке на Windows, NPM входит в состав Node.js по умолчанию. Для Linux необходимо устанавливать NPM отдельно.
2. Проверка корректности установки
После установки, откроем терминал и проверим версии Node.js и NPM. Если в ответ получим номер версии - значит установлено корректно.
node -v # проверяем версию Node.js
npm -v # проверяем версию NPM
Установка NPX-пакета с готовой архитектурой
1. Установка create-vuepress-site
Создаем директорию для проекта и открываем в редакторе. Вызываем терминал из текущей директории и устанавливаем пакеты:
npx create-vuepress-site
После этого VuePress попросит указать данные для настройки файла "package.json"
: название проекта, описание и прочее. Файл "package.json"
потребуется для установки npm-пакетов и запуска скриптов.
В итоге, будет создана базовая структура:
Корневая директория "docs"
подразумевает использование VuePress внутри рабочего проекта. Мы будем разрабатывать только документацию, поэтому уберем лишний уровень вложенности: удалим директорию "docs"
, а всё содержимое поместим в корень проекта.
2. Запуск проекта
Настало время запустить проект. Для этого перейдём в файл "package.json"
и посмотрим на уже подготовленные скрипты.
"scripts": {
"dev": "vuepress dev src",
"build": "vuepress build src"
}
Скрипт
"dev"
запустит приложение на локальном сервереСкрипт
"build"
соберет приложение для production
Запуск скриптов осуществляется через терминал:
npm run dev
npm run build
При запуске скрипта "dev"
, в терминале будет сообщение об успешной сборке и адрес локального сервера: http://localhost:8080/.
success [11:09:20] Build 257d7d finished in 4856 ms!
> VuePress dev server listening at http://localhost:8080/
Главная страница стартового приложения состоит из поиска по разделам, страницы "Guide", страницы "Config" и контента.
Отредактировать страницы можно в следующих файлах:
"./src/index.md"
- главная страница"./src/config/README.md"
- страница "Config""./src/guide/README.md"
- страница "Guide"
Установка NPX-пакета с готовой архитектурой позволяет быстро развернуть приложение с базовым набором страниц. Но вместо того чтобы проводить рефакторинг и оптимизировать полученный шаблон под себя, предлагаю самостоятельно развернуть проект и последовательно разобраться с функционалом VuePress.
Разработка приложения на VuePress с нуля
Создадим новый проект и откроем его в терминале.
1. Инициализация проекта
npm init # инициализация с указанием настроек проекта
npm init -y # инициализация с дефолтными настройками
После инициализации проекта создается файл "package.json"
. При установке с дефолтными настройками ("npm init -y"
), файл выглядит следующим образом:
{
"name": "vue-press",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Где "vue-press"
в поле "name"
- это название директории проекта.
2. Установка VuePress
Выполним команду в терминале:
npm i --save-dev vuepress
В проекте появится директория "node_modules"
с пакетами, необходимыми для работы VuePress. В файл "package.json"
добавится секция "devDependencies"
с установленным пакетом.
"devDependencies": {
"vuepress": "^1.8.2"
}
В раздел "devDependencies"
помещаются пакеты, необходимые только на этапе разработки.
3. Добавление скриптов
Скорректируем секцию "scripts"
в файле "package.json"
. Скрипт "test"
не пригодится - поэтому его можно удалить. Следуя документации VuePress, добавим 2 скрипта. Секция "scripts"
будет выглядеть следующим образом:
"scripts": {
"start": "vuepress dev src",
"build": "vuepress build src"
}
Скрипт
"start"
запустит приложение на локальном сервереСкрипт
"build"
соберет приложение для production
Рассмотрим параметры для скриптов:
"vuepress dev src"
для скрипта"start"
, запустит"vuepress"
в режиме разработки и будет искать нужные файлы в директории"src"
"vuepress build src"
для скрипта"build"
, запустит"vuepress"
в production-режиме, будет искать нужные файлы в директории"src"
и соберет проект для production
Для запуска скриптов также используем:
npm run start
npm run build
На данном этапе не заложена структура приложения, поэтому скрипты выполняться не будут.
4. Разработка архитектуры приложения
Разработаем архитектуру приложения, как показано на изображении:
Основные директории и файлы:
"./src/index.md"
- точка входа в приложение"./src/.vuepress/"
- директория с настройками VuePress"./src/pages"
- директория со страницами
Разберем алгоритм работы приложения и его архитектуру:
При выполнении скрипта
"start": "vuepress dev src"
, VuePress запускается в режиме разработки с указанием рабочей директории"src"
В
"src"
находится точка входа в приложение: файл"index.md"
, содержимое которого рендерится на главную страницуVuePress ищет в
"src"
директорию".vuepress"
для чтения настроек (директория должна называться именно так)В файле
"./src/.vuepress/config.js"
находятся все настройки по работе VuePress. Происходит сопоставление страниц приложения и роутов: здесь мы указываем, что именно в"pages"
хранятся все страницыДиректория
"pages"
содержит все страницы приложения. В нашем случае, их всего две: с темами по React.js (директория"react"
) и по Vue.js (директория"vue"
). Страницы приложения были придуманы абстрактноДля каждой страницы (директория
"pages"
) должен быть файл"README.md"
. Он выполняет функцию, аналогичную"./src/index.md"
. Кроме этого, добавлен файлы"info.md"
для каждой темы - это произвольные описательные страницы
5. Markdown-файлы
Из файлов с расширением ".md"
, код компилируется в HTML-страницы.
Код в файлах ".md"
можно писать:
На языке Markdown
Используя YAML Front Matter
На чистом HTML
В статье мы будем использовать Markdown, позволяющий максимально быстро разметить контент.
Откроем последовательно файлы ".md"
и добавим произвольный контент. Символ "#"
в Markdown добавляет заголовок первого уровня.
./src/index.md
# Главная страница приложения
./src/pages/react/README.md
# Главная страница справочника по React.js
./src/pages/react/info.md
# Описание фреймворка React.js
./src/pages/vue/README.md
# Главная страница справочника по Vue.js
./src/pages/vue/info.md
# Описание фреймворка Vue.js
6. Файл config.js
Осталось указать, что страницы необходимо брать из директории "pages"
.
Базовая структура конфигурации "./src/.vuepress/config.js"
:
module.exports = {
themeConfig: {
// Ссылки на разделы
nav: [
{
text: 'Название раздела',
link: 'Путь к разделу'
},
],
// Ссылки внутри раздела
sidebar: {
'Путь к разделу': [
{
title: 'Название подраздела', //
children: [
['Путь к теме', 'Название темы'],
]
}
]
}
},
}
В качестве импорта и экспорта используется CommonJS (модульная система Node.js), поэтому указываем "module.exports"
.
Проведём оптимизацию и вынесем в константы роуты (в нашем случае, это "nav"
и "sidebar"
).
// Константы с роутами к страницам
const PAGE_VUE = '/pages/vue/';
const PAGE_REACT = '/pages/react/';
// Ссылки на разделы
const NAV = [
{
text: 'Vue.js',
link: PAGE_VUE
},
{
text: 'React.js',
link: PAGE_REACT
},
];
// Ссылки внутри раздела
const SIDEBAR = {
[PAGE_VUE]: [
{
title: 'Информация',
children: [
['info', 'Vue.js'],
]
}
],
[PAGE_REACT]: [
{
title: 'Информация',
children: [
['info', 'React.js'],
]
}
]
};
module.exports = {
themeConfig: {
nav: NAV,
sidebar: SIDEBAR
},
}
7. Запуск приложения
Запустим терминал из рабочей директории и выполним скрипт:
npm run start
Переходим по адресу: http://localhost:8080/.
На главной странице видим текст из "./src/index.md"
. В меню отображаются две ссылки: "Vue.js" и "React.js".
Перейдем на вкладку "Vue.js". URL изменился на http://localhost:8080/pages/vue/. На странице видим текст из "./src/pages/vue/README.md"
.
В сайдбаре в разделе "Информация" выберем "Vue.js". URL изменился на http://localhost:8080/pages/vue/info.html. На странице видим текст из "./src/pages/vue/info.md"
.
Поздравляю! Мы разработали минимальное приложение на VuePress. Теперь посмотрим на дополнительный функционал.
8. Добавление изображений
Добавим новую директорию "img"
в "./src/pages/vue"
(по аналогии можно добавить и для "./src/pages/react"
). Поместим в "img"
изображение "vue-logo.jpg"
.
Теперь из файла "./src/pages/vue/info.md"
можно получить доступ к изображению.
<!-- Markdown-формат -->
![Alt for Image](./img/vue-logo.jpg)
<!-- HTML-формат -->
<img src="./img/vue-logo.jpg" width="200px" alt="Alt for Image" />
При использовании HTML-формата возможно указать ширину изображения, что во многих ситуациях, будет удобнее разметки Markdown.
Для изображений можно задавать не только относительные путь, но и абсолютные. Некоторые изображения должны быть доступны не только в рамках одной страницы, а во всём приложении. Такие изображения необходимо добавлять в "./src/.vuepress/public"
. Обратиться к ним можно напрямую, указывая "/"
или через Vue-переменную "$withBase"
.
<!-- Использование пути "/" -->
<img src="/vue-logo.jpg" alt="Alt for Image" />
<!-- Использование Vue-переменной -->
<img :src="$withBase('/vue-logo.jpg')" alt="Alt for Image" />
9. Добавление favicon и meta-данных
Favicon разместим в директории, содержащей общие ресурсы: "src/.vuepress/public/favicon.svg"
После этого в конфиге "src/.vuepress/config.js"
укажем favicon в разделе "head"
. Кроме favicon, в данном разделе можно добавить meta-данные для нашего приложения:
module.exports = {
themeConfig: {
//
},
head: [
['link', { rel: 'icon', href: '/favicon.svg' }],
['meta', { name: 'theme-color', content: '#3eaf7c' }],
['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }]
]
}
10. Изменение цветовой схемы
По умолчанию, для приложения VuePress задана стандартная цветовая схема, но ее можно изменить. Для этого создадим директорию "styles"
в "./src/.vuepress/"
. В "styles"
добавим два файла на препроцессоре "Stylus"
(это дефолтный препроцессор в VuePress):
"index.styl"
- содержит общие стили для приложения (н-р: можно добавить стили ко всем изображениям)."palette.styl"
- содержит переменные цветовой схемы, которые можно переопределить.
Для файла "palette.styl"
доступны следующие переменные:
$accentColor = #3eaf7c
$textColor = #2c3e50
$borderColor = #eaecef
$codeBgColor = #282c34
Корректируя значения, можно изменить цветовую схему приложения.
11. Подключение поиска
Поиск осуществляется с помощью технологии Algolia: индексируются все заголовки первого, второго и третьего уровней (h1-h3), и в дальнейшем, поиск происходит именно по ним.
Для подключения поиска, в конфиге "src/.vuepress/config.js"
достаточно указать "search: true"
:
module.exports = {
themeConfig: {
search: true,
},
}
Проверим работу поиска. На данный момент, у каждой страницы присутствует заголовок первого уровня. Вводим в поиск часть слова, и по итогу получим ссылки на страницы с совпадением.
Добавим еще несколько заголовков второго, третьего и четвертого уровней в любой из Markdown-файлов. После этого можно будет заметить, что индексируются только заголовки первого, второго и третьего уровня. Поиск по заголовку четвертого уровня не осуществляется.
12. Использование Vue-компонентов
VuePress использует фреймворк Vue.js - следовательно, можно добавлять кастомные Vue-компоненты в наши Markdown-файлы.
Создадим директорию "components"
в "./src/.vuepress/"
, в которой будут находиться кастомные vue-компоненты (название директории должно быть именно таким):
Создадим простой vue-комопнент в директории "components"
. Назовём его "v-hello.vue"
- он будет выводить приветствие для пользователя с указанным именем.
<template>
<div class="wrapper">
Hello, {{name}}!
</div>
</template>
<script>
export default {
props: ['name']
}
</script>
<style scoped>
.wrapper {
padding: 10px;
margin: 10px 0;
font-weight: 600;
background-color: #44e4d6;
}
</style>
Вызывать компонент можно из любого Markdown-файла страниц. Пример вызова компонента:
<v-hello name="Tony" />
Результат вызова:
13. Сборка проекта
Для сборки проекта используется скрипт:
npm run build
После успешной сборки, собранный проект будет находиться в "./src/.vuepress/dist"
. Посмотрим на структуру директории "dist"
:
Структура директории:
Директория
"assets"
- ресурсы для страницДиректория
"pages"
- сами страницы: "react" и "vue"Страница 404 сгенерировалась автоматически
Корневые файлы
"favicon.svg"
и"favicon.svg"
- были взяты из"./src/.vuepress/public"
.Файл
"index.html"
- стартовая страница
Проект представляет собой статичные файлы, готовые к загрузке на сервер.
Обратим внимание на задание путей в файлах ".html"
. Для примера, возьмем файл "./src/.vuepress/public/index.html"
. В этом файле я оставил только некоторые пути для демонстрации:
<!DOCTYPE html>
<html>
<head>
<link rel="icon" href="/favicon.svg">
<link rel="preload" href="/assets/css/0.styles.96af6c87.css">
...
</head>
<body>
...
<script src="/assets/js/app.b24ed5d1.js" defer></script>
...
</body>
</html>
Пути начинаются с "/"
- это значит, что файлы будут искаться в корневой директории. К примеру, для сайта "https://mysite.ru"
, "favicon.svg"
должен находиться в корне проекта.
Но что если, проект располагается по адресу "https://mysite.ru/vue-press"
и файл "favicon.svg"
находится в директории "vue-press-sample"
? В таком случае, путь к "favicon.svg"
будет некорректен:
<!-- Некорректно -->
<link rel="icon" href="/favicon.svg">
<!-- Корректно -->
<link rel="icon" href="/vue-press-sample/favicon.svg">
Для задания корневого URL сборки необходимо изменить конфиг VuePress.
14. Задание корневого URL
Если приложение будет находиться в директории, отличной от корневой, то скорректируем раздел "base"
в файле "./src/.vuepress/config.js"
:
module.exports = {
themeConfig: {},
base: '/vue-press-sample/',
}
В разделе "base"
я указал название своего будущего GitHub-репозитория, т.к. при деплое на GitHub Pages, в качестве адреса будет браться его название.
Запустим сборку проекта "npm run build"
и посмотрим на файл "./src/.vuepress/public/index.html"
. Опять же, для демонстрации, я привёл только часть файла:
<!DOCTYPE html>
<html>
<head>
<link rel="icon" href="/vue-press-sample/favicon.svg">
<link rel="preload" href="/vue-press-sample/assets/css/0.styles.96af6c87.css">
...
</head>
<body>
...
<script src="/vue-press-sample/assets/js/app.b24ed5d1.js" defer></script>
...
</body>
</html>
Видно, что в пути для каждого файла добавилось "/vue-press-sample/"
- это то, что мы указывали в файле конфига в разделе "base"
.
Таким образом, мы получили сборку нашего приложения, готовую для загрузки на GitHub и GitHub Pages.
15. Деплой на GitHub
Для начала добавим файл ".gitignore"
в корень проекта. Судя из названия, мы можем прописать в нём файлы или директории, которые не следует загружать на GitHub.
На GitHub загружаем только исходные файлы. Всё что можно собрать или установить, загружать не нужно.
Что вынесем в игнор:
"node_modules"
- установленные npm-пакеты. При клонировании репозитория, выполняем команду"npm i"
и из файла"package.json"
происходит установка всех пакетов."./src/.vuepress/dist"
- сборка нашего приложения. При клонировании репозитория, выполняем команду"npm run build"
и сборка готова.
Файл ".gitignore"
будет выглядеть следующим образом:
node_modules
src/.vuepress/dist
Загрузим проект на GitHub. Для этого можно воспользоваться любимыми инструментами: GitHub Desktop, командной строкой или другими приложениями.
По итогу, получим GitHub-репозиторий с проектом:
Мой проект можно посмотреть по ссылке.
Переходим к деплою на GitHub Pages.
16. Деплой на GitHub Pages
Для GitHub Pages по умолчанию используется ветка "gh-pages"
репозитория, но при желании, в настройках в секции "Pages"
можно указать и другую:
Для деплоя, можно вручную вручную создать ветку "gh-pages"
и загрузить сборку приложения - директорию "src\.vuepress\dist"
, которая создаётся при выполнении команды "npm run build"
. Но это не столь удобно.
Для автоматизации установим npm-пакет "gh-pages"
. При этом, будет достаточно только запустить npm-скрипт и пакет самостоятельно создаст ветку "gh-pages"
(если ее еще не было) и загрузит фалы сборки.
npm i gh-pages --save-dev
После установки, в файле "package.json"
добавим 2 скрипта:
"scripts": {
"build-gh-pages": "gh-pages -d src/.vuepress/dist",
"deploy": "npm run build && npm run build-gh-pages"
},
Скрипт
"build-gh-pages"
возьмёт файлы сборки из"src/.vuepress/dist"
и запустит пакет"gh-pages"
Скрипт
"deploy"
- группирует существующие скрипты и выполняет их в определенном порядке: делаем сборку приложения, потом запускам работу пакета"gh-pages"
Также, в секцию "homepage"
пропишем адрес нашего репозитория (для вас адрес будет другим):
{
"homepage": "https://github.com/dev-pandaren/vue-press-sample",
}
dev-pandaren
- название аккаунтаvue-press-sample
- название репозитория
Итоговый вид файла "package.json"
будет выглядеть следующим образом:
{
"name": "vue-press",
"version": "1.0.0",
"homepage": "https://github.com/dev-pandaren/vue-press-sample",
"main": "index.js",
"scripts": {
"start": "vuepress dev src",
"deploy": "npm run build && npm run build-gh-pages",
"build": "vuepress build src",
"build-gh-pages": "gh-pages -d src/.vuepress/dist"
},
"devDependencies": {
"gh-pages": "^3.1.0",
"vuepress": "^1.5.3"
}
}
Запустим скрипт "deploy"
: произойдет сборка приложения и деплой на GitHub Pages. Если вы не авторизованы на GitHub, то появится окно, предлагающее это сделать.
Сообщения в консоли будут выглядеть подобным образом:
Перейдем на GitHub и увидим еще одну ветку "gh-pages"
, в которой будет сборка нашего приложения:
Вот и всё! После создания ветки "gh-pages"
, GitHub возьмёт файлы сборки и создаст GitHub Pages - для этого потребуется некоторое время (до 24 часов).
Если мы перейдем обратно в настройки репозитория и выберем секцию "Pages"
, то увидим ссылку на страницу GitHub Pages. При этом, в разделе "Source", необходимо выбрать ветку "gh-pages"
, если она не была выбрана.
В моём случае это: https://dev-pandaren.github.io/vue-press-sample/
Разберем адрес по частям:
dev-pandaren
- название аккаунта.github.io
- домен для GitHub Pagesvue-press-sample
- название репозитория
Переходим по указанному адресу GitHub Pages и видим наше приложение:
На этом мы завершили разработку и деплой простого приложения на VuePress. Ниже привожу основные ссылки.