Данное описание может быть полезным при деплое SPA которое работает с использованием события popstate
и разделением ресурсов в строке браузера через /
Основное затруднение при деплое SPA приложения начинается в момент когда, пользователь выполняет ввод в строке браузера необходимого ресурса внутри приложения (например - другой страницы) и браузер выполняет запрос на сервер за указанным ресурсом. Так как этот ресурс не найден возвращается страница 404.html
для сервиса GitHub (или Cannot GET /
для других сервисов или серверов).
Это нарушает работу SPA, которому необходима страница index.html
(или другая в вашем приложении), в которой подключены необходимые скрипты приложения являющиеся точкой входа в приложение и способные проанализировать строку браузера и выполнить нужное действие.
При этом если переход между компонентами выполняется нажатием какой-либо кнопки (ссылки) внутри приложения, то все работает корректно, т.к. страница не перезагружается и скрипт не теряет управление. Отменить запрос браузера к серверу при вводе в строке мы не сможем.
В основе лежит возможность сервиса gh-pages
заменить базовую страницу 404.html
другой, которая может содержать необходимую приложению логику.
Примеры описанные в данном репозитории используют скрипты и идею приведенную в репозитории https://github.com/rafgraph/spa-github-pages
В данном описании указаны не все действия, производимые скриптами со строкой браузера. Для детальной информации изучите https://github.com/rafgraph/spa-github-pages
В данном репозитории размещены два каталога:
- Каталог
one-app
содержит файлы для размещения в одном репозитории одного приложения. - Каталог
many-app
содержит файлы для размещения в одном репозитории нескольких приложений находящихся в разных каталогах.
В данном репозитории выполнен деплой второго варианта со множеством приложений размещенных в разных каталогах - первое приложение и второе приложение
При выполнении деплоя вам необходимо обратить внимание на размещение и содержимое файлов index.html
и 404.html
В каждом из файлов добавлен тег <script>
внутри которого находится код выполняющий действия необходимые для правильного перенаправления при вводе в строке браузера.
- В корне репозитория должен быть размещен файл
404.html
. - В файле
404.html
в секции скриптов определена переменнаяpathSegmentsToKeep
, которая отвечает за переадресацию со страницы404.html
на страницуindex.html
. - Число указанное в переменной
pathSegmentsToKeep
указывает сколько сегментовpathname
вwindow.location
требуется пропустить скрипту до места размещения файлаindex.html
.
На примере деплоя переменнаяpathSegmentsToKeep
равна 2 и в строке браузера видаhttps://mikaleinik.github.io/spa-deploy/app1/main
вpathname
будет учитываться, что первые 2 сегмента/spa-deploy/app1/
это путь к файлуindex.html
. - Скрипт размещенный в
404.html
после переменнойpathSegmentsToKeep
выполняет замену строки и переадресацию на файлindex.html
. В результате работы скрипта строка браузера видаhttps://mikaleinik.github.io/spa-deploy/app1/main
приобретет видhttps://mikaleinik.github.io/spa-deploy/app1/?/main
, что позволит выполнить страницуindex.html
размещенную по адресуhttps://mikaleinik.github.io/spa-deploy/app1/
. - В каталоге каждого приложения в файле
index.html
добавлен скрипт, который выполняет обратную модификацию строки браузера и удаляет артефакты добавленные скриптом в404.html
.
В результате строка видаhttps://mikaleinik.github.io/spa-deploy/app1/?/main
преобразовывается кhttps://mikaleinik.github.io/spa-deploy/app1/main
. - Т.к. приложение размещено не в корне репозитория, то для полноценной загрузки подключенных скриптов в файле
index.html
требуется корректно указать<base href="/repository/catalog/">
.
На примере деплоя - для первого приложения это<base href="/spa-deploy/app1/">
и для второго<base href="/spa-deploy/app2/">
- После работы скрипта в
index.html
приложение будет загружено и необходимы дальнейшие для показа нужного компонента. - Для примера в приложениях реализована усеченная логика компонента роутинга в зависимости от содержимого строки браузера или вызова из приложения.
Переход между страницами возможен как по набору в строке браузера, так и в форме ввода на каждой странице. - При инициализации приложения указывается переменная
pathSegmentsToKeep
со значением равным аналогичной переменной в файле404.html
. - Значение переменной указывает роутеру какое количество сегментов
pathname
пропустить для анализа строки браузера. После пропущенных сегментов последующие определяют нужную страницу (компонент) и параметры для нее (если требуются) соответственно.
На примере деплоя по строке видаhttps://mikaleinik.github.io/spa-deploy/app1/main
в роутере будет пропущено 2 сегмента (/spa-deploy/app1
) и будет выбран маршрут/main
по которому вызовется необходимый компонент.