В этом руководстве мы рассмотрим сайт 521dimensions.com и наш проект с открытым исходным кодом AmplitudeJS, документы которого теперь написаны на VuePress и расположены по адресу https://521dimensions.com/open-source/amplitudejs/docs.

Наш сайт 521dimensions.com написан на Laravel 5.6, а вся документация по AmplitudeJS находится на VuePress. Приятно иметь документы в одном домене и выглядеть как еще один маршрут на сайте.

Как я структурировал установку

Это первая часть, в которой я почувствовал, что могу быть другим. Если у вас есть альтернативы или предложения, обязательно дайте мне знать! Итак, я сделал 2 каталога. У нас есть каталог /521dimensions.com, и я создал каталог /amplitude-docs вне фактического сайта.

Причина, по которой я сделал это, заключалась в том, что я использую Laravel-Mix для компиляции ресурсов 521dimensions.com. Laravel Mix великолепен, однако он находится в веб-пакете 3. Если вы читали руководство по установке VuePress (Начало работы | VuePress), вы не можете установить Vuepress как локальную зависимость с веб-пакетом 3. НЕ ПРОБЛЕМА VUEPRESS, но проблема веб-пакета. Веб-пакет сгенерирует неправильное дерево зависимостей, и все пойдет напрасно. Они рекомендуют использовать Yarn, но установка Yarn и Using NPM кажется большой головной болью, и я читал, что вы даже не можете заставить их работать вместе.

Другой вариант - выполнить глобальную установку vuepress. Подумал об этом, но я предпочитаю, чтобы все было локально, когда это возможно. Вот почему я сделал еще один каталог под названием /amplitude-docs.

Установка VuePress

Я не буду вдаваться в подробности установки Vuepress, так как в руководстве: Начало работы | VuePress прекрасно с этим справляется. Я создал новый проект NPM в каталоге /amplitude-docs. Затем я последовал руководству по началу работы с VuePress и выполнил:

npm install -D vuepress

Это установило VuePress как локальную зависимость в проекте. Затем я создал каталог /amplitude-docs/docs. Затем я поместил файл README.MD в этот каталог и создал скрытый каталог .vuepress.

В каталоге /docs вы можете добавлять папки, содержащие документацию в Markdown для вашего приложения. В конфигурации VuePress вы можете установить, как вы хотите, чтобы они были структурированы на боковой панели, но это зависит от темы, которую вы используете. Обратите внимание, что эквивалент файла index.html - файл README.md. Вы будете добавлять по одному в каждый из своих каталогов.

Настройка VuePress для работы с Laravel

Теперь в скрытом каталоге .vuepress я добавил файл config.js. Для документов AmplitudeJS я просто использую тему по умолчанию, предоставленную VuePress. Мне нравится эта тема, и я настроил ее под свои нужды. Вы можете проверить живую документацию здесь: Обзор - Документация AmplitudeJS. Если вы хотите знать, как я настроил или сделал что-то с VuePress, чтобы документы работали определенным образом, я буду рад помочь, просто прокомментируйте ниже! Однако любая конфигурация, выходящая за рамки того, что я сделал для работы VuePress с Laravel, выходит за рамки этого руководства.

С учетом сказанного откройте ваш .vuepress/config.js файл. В VuePress есть опция base. Это ЧРЕЗВЫЧАЙНО важно, чтобы эта работа работала как подкаталог в Laravel. Прежде чем мы это установим, обратите внимание на две команды:

  1. npm run docs:dev
  2. npm run docs:build

Эти две команды настраиваются при установке VuePress. Первая команда npm run docs:dev запускает локальный URL-адрес разработки, чтобы вы могли видеть свои документы по мере их добавления. npm run docs:build фактически компилирует всю вашу документацию в готовое приложение, которое вы можете развернуть в различных местах: Развертывание | VuePress . В нашем случае мы будем развертывать его на нашем сервере.

Вернемся к конфигурации base. Если вы посмотрите URL-адрес наших документов AmplitudeJS по адресу https://521dimensions.com/open-source/amplitudejs/docs, заметите, как он находится в каталоге /open-source/amplitudejs/docs? Это будет вашей базой! Ваша конфигурация для VuePress должна выглядеть так:

module.exports = {
  title: '',
  description: 'Official documentation for AmplitudeJS',
  base: '/open-source/amplitudejs/docs/',
}

Здесь заключается еще один шаг настройки, который мне не нравится. При создании документов и их тестировании вам следует УДАЛИТЬ базовую конфигурацию, иначе она не будет работать, поскольку не будет соответствовать структуре каталогов вашего приложения VuePress. Когда я тестирую свои документы, я удаляю базу, позволяю VuePress запускать URL-адрес разработки на https://localhost:8080 или в другом месте, которое вы настроили, а затем перед сборкой я добавляю свою base конфигурацию. Может быть, вы могли бы удалить это в зависимости от команды узла? Это мог быть другой вариант. В любом случае, если подвести итог, ваша base конфигурация должна соответствовать подкаталогу, в котором ваши документы будут находиться на вашем маршруте в вашем приложении Laravel.

Прямо сейчас приступайте к созданию своих документов! Добавьте Markdown в свои каталоги, протестируйте и доведите до того места, где вы хотите развернуть. Конечно, если вы находитесь на этом этапе и у вас есть вопросы о конкретной конфигурации VuePress, которую я настроил, обращайтесь ниже! Затем мы переместим скомпилированные документы в наше приложение Laravel.

Создание нашей документации для развертывания

Созданные вами документы готовы к развертыванию! Чтобы создавать свои документы в Vuepress, убедитесь, что ваш base настроен на соответствие подкаталогу или подмаршруту, в котором они будут находиться в вашем приложении Laravel. В нашем случае это /open-source/amplitudejs/docs. Затем запустите npm run docs:build. Ваша документация будет скомпилирована в одностраничное приложение, отображаемое на стороне сервера. По сути, это набор HTML, CSS, Javascript и изображений, используемых в ваших документах.

Когда npm run docs:build завершится, документы будут скомпилированы и помещены в каталог /docs/.vuepress/dist. По сути, это то, что вы хотите скопировать в свое приложение Laravel! Это ваши готовые к производству документы, они содержат все, что вам нужно.

Теперь вот, еще один шаг. Вам нужно будет разместить эти документы в общедоступном каталоге в вашем приложении Laravel. Сейчас я предполагаю, что ваши документы не содержат конфиденциальной информации. ЕСЛИ ОНИ ДЕЙСТВУЮТ, НЕ размещайте их в общедоступном каталоге. Свяжитесь с нами, и я могу помочь заблокировать ваши документы с помощью политики авторизации.

Сейчас предположим, что все документы общедоступны. Я буду помещать свои документы в каталог /public/docs/amplitudejs в моей установке Laravel. Чтобы упростить мне задачу в моей среде разработки, в VuePress я написал простой скрипт узла, который был npm run docs:deploy. Это буквально копирует каталог скомпилированных документов /docs/.vuepress/dist в каталог /public/docs/amplitudejs в моей установке Laravel. Вы можете скопировать это как хотите.

Теперь, когда наши документы находятся внутри нашей установки Laravel, нам нужно сделать несколько уловок, чтобы заставить их работать!

Настройка Laravel для работы с VuePress

Это уловка. Мы хотим, чтобы наши документы располагались по адресу https://521dimensions.com/open-source/amplitudejs/docs. Это внутри нашей установки Laravel и по указанному нами маршруту. Как я упоминал ранее, когда мы создавали наши документы для производства, мы устанавливали нашу базу как /open-source/amplitudejs/docs. Это настраивает всю конфигурацию и маршрутизатор VuePress так, чтобы документы были в этом каталоге. Это хорошо, потому что все ссылки фактически соответствуют URL-адресу даже в одностраничном приложении! Представьте себе, что! Ваш Google Analytics также будет работать, если вы их настроили.

Итак, на последнем этапе мы скопировали все готовые к производству документы в общедоступный каталог по адресу /public/docs/amplitudejs в установке Laravel.

Нашим первым шагом является добавление фактических маршрутов в Laravel, с которыми мы хотим загрузить документы. Напоминаю, что у меня есть файл AmplitudeController.php, который обрабатывает все маршруты, относящиеся к нашему разделу AmplitudeJS на сайте, такие как целевая страница, примеры и т. Д. Мы используем Laravel 5.6, поэтому нам нужно открыть файл /routes/web.php и добавить следующие маршруты :

Route::get('/open-source/amplitudejs/docs/', 'AmplitudeController@getAmplitudeDocsAsset');
Route::any('/open-source/amplitudejs/docs/{asset}', 'AmplitudeController@getAmplitudeDocsAsset')->where('asset', '.*');

По этим двум маршрутам происходит множество событий. Первый - это, по сути, заполнитель, чтобы сказать: «Эй, мы собираемся вернуть документы по этому адресу». Второй - это подстановочный знак, и он действительно является одним из основных ключей к тому, чтобы документы VuePress работали в laravel. Помните ту базу, которую мы создали? НУ, вот где дело доходит до игры. Все ресурсы доступны из VuePress по этому базовому URL. Второй маршрут присваивает НИЧЕГО после /docs части URL-адреса $asset переменной. Буквально это может быть что угодно. Это перехватывает ВСЕ запросы на загрузку ресурсов, которые мы будем перехватывать и возвращать из нашего общедоступного каталога. По сути, мы проксируем ВСЕ запросы, загружаем связанный файл из общедоступного каталога и возвращаем его.

Обратите внимание, что два маршрута обращаются к одному и тому же методу на AmplitudeController.php? Это не по ошибке. Нам нужен только один метод, чтобы делать все!

Давайте посмотрим на этот метод:

public function getAmplitudeDocsAsset( $asset = 'index.html' ){

  /*
    Disable new relic auto run so we don't get extra JS that will
    break the VuePress SPA
  */
  if (extension_loaded('newrelic')) {
    newrelic_disable_autorum();
  }

  /*
    If the extension is javascript, css, svg or does NOT
    contain .html redirect to the page they requested and the
    index.html file within that directory.
  */
  if( pathinfo( $asset, PATHINFO_EXTENSION ) != 'js'
      && pathinfo( $asset, PATHINFO_EXTENSION ) != 'css'
      && pathinfo( $asset, PATHINFO_EXTENSION ) != 'svg'
      && strpos( $asset, '.html' ) == null ){
        return redirect( '/open-source/amplitudejs/docs/'.$asset.'/index.html' );
  }

  /*
    Get the contents of the asset. This can be CSS, JS, images or HTML.
  */
  $contents = File::get(public_path() . '/docs/amplitudejs/'.$asset );

  /*
    Build a response with the asset being requested.
  */
  $response = Response::make($contents);

  /*
    If the asset is CSS, ensure the Content-Type text/css header is passed
    along with the file.
  */
  switch( pathinfo($asset, PATHINFO_EXTENSION) ){
    case 'css':
        $response->header('Content-Type', 'text/css');
    break;
  }

  /*
    Return the response
  */
  return $response;
}

В этом методе происходит МНОГОЕ, поэтому давайте разберемся с ним. По сути, это ключ к тому, чтобы ВСЕ работало.

Сначала мы отключаем NewRelic (если вы используете NewRelic для мониторинга или что-то еще):

/*
  Disable new relic auto run so we don't get extra JS that will
  break the VuePress SPA
*/
if (extension_loaded('newrelic')) {
  newrelic_disable_autorum();
}

Нам нужно отключить это, потому что они добавляют дополнительный javascript в наше приложение. Это сильно ломает VuePress SPA! На данный момент мы этого не хотим.

Затем мы проверяем, к какому URL-адресу получил доступ пользователь:

/*
  If the extension is javascript, css, svg or does NOT
  contain .html redirect to the page they requested and the
  index.html file within that directory.
*/
if( pathinfo( $asset, PATHINFO_EXTENSION ) != 'js'
    && pathinfo( $asset, PATHINFO_EXTENSION ) != 'css'
    && pathinfo( $asset, PATHINFO_EXTENSION ) != 'svg'
    && strpos( $asset, '.html' ) == null ){
      return redirect( '/open-source/amplitudejs/docs/'.$asset.'/index.html' );
}

Если URL-адрес не является Javascript, CSS, SVG и не содержит .html, мы предполагаем, что пользователь хочет просмотреть часть документации. Это часть трюка. Помните, что мы проксируем все ресурсы для загрузки через этот маршрут, поэтому страница может запрашивать ресурсы Javascript, CSS или изображения. Нам не нужно это перенаправление, если они запрашивают любой из них. Теперь у нас есть это для перенаправления в файл index.html для соответствующего подкаталога. Это значит, что VuePress правильно запускает SPA. Не большой поклонник этой части, но она должна работать именно так, чтобы не пройти 404, когда вы пытаетесь ориентироваться.

Следующая часть метода довольно приятная:

/*
  Get the contents of the asset. This can be CSS, JS, images or HTML.
*/
$contents = File::get(public_path() . '/docs/amplitudejs/'.$asset );

/*
  Build a response with the asset being requested.
*/
$response = Response::make($contents);

/*
  If the asset is CSS, ensure the Content-Type text/css header is passed
  along with the file.
*/
switch( pathinfo($asset, PATHINFO_EXTENSION) ){
  case 'css':
      $response->header('Content-Type', 'text/css');
  break;
}

/*
  Return the response
*/
return $response;

Что это значит, так это получить запрашиваемый актив по общедоступному пути. У нас есть переменная $asset, содержащая по существу URL-адрес относительно docs, сгенерированного VuePress. Это та же структура, что и в нашем каталоге public, поэтому мы можем захватить сам файл с помощью помощника public_path() в Laravel, добавив источник, в котором мы разместили файл, и захватить файл на основе параметра $asset.

Затем мы отправляем ответ, используя фасад Response, который поставляется с Laravel, и передаем ему содержимое только что загруженного файла.

Единственная проблема, прежде чем мы вернем ответ, - это то, что Laravel не добавит правильный заголовок для Content-Type, если файл является файлом CSS. Это становится проблемой, потому что браузер интерпретирует его как текст и не обрабатывает CSS-код для некрасивой страницы. Итак, что мы делаем, это проверяем, является ли расширение переменной $asset css. Если это так, мы бросаем быстрый заголовок для Content-Type: text/css, чтобы он был интерпретирован правильно.

Наконец, мы возвращаем $response вместе с файлом. Это все, что нам нужно сделать, чтобы VuePress работал в Laravel! По сути, мы устанавливаем базу документов VuePress, на которую будем ссылаться через маршрут Laravel. Затем мы перемещаем файлы в общедоступный каталог и пишем прокси для любых запросов из VuePress SPA, которые будут обрабатываться нашим прокси для всех изображений, скриптов, стилей, HTML и т. Д.

Вывод

Это своего рода способ заставить это работать. Как только я заработал, я очень доволен результатами. Вы можете увидеть живую документацию AmplitudeJS, написанную на VuePress, через наше приложение Laravel здесь: Обзор - Документация AmplitudeJS. Позвольте мне знать ваши мысли! Конечно, если есть вопросы, опасения, нужна дополнительная информация или у вас есть способ сделать что-то лучше, обращайтесь! Комментарии ниже! Я очень верю в VuePress как в будущее документации, и было бы здорово сделать этот процесс более эффективным!