одностраничное приложение Реагирует на URL-адреса маршрутов с помощью Express. Но НЕ используйте create-реагировать-приложение или службы развертывания, такие как Heroku - PullRequest
1 голос
/ 22 мая 2019

Моя проблема очень распространена: у меня есть одностраничное приложение React, все работает нормально, но подстраницы URL не будут загружаться при переходе непосредственно или обновлении.

Я потратил часы (возможно, дни) на поиски многие посты / статьи / учебники на форуме, написанные об этой проблеме, предполагают использование платформы развертывания, такой как Heroku или Digital Ocean, которая либо выполняет часть работы за вас, либо, возможно, имеет какую-то запутанную связанную работу, с которой я не могу разобратьсяимеет смысл для моего конкретного приложения.

Обсуждение, в котором не участвуют специальные платформы развертывания, всегда предполагает, что я создал свое приложение с помощью create-реагировать-приложение, чего я не сделал.Я попытался воссоздать процесс в create-реагировать-приложение, которое заставляет маршрутизацию одностраничного приложения работать должным образом (npm build запрограммирован, чтобы node запустить react-scripts.js из packages/react-scripts/bin, но код в реагирующих сценариях.js сразу немного более продвинут, чем мой уровень квалификации, и, кажется, также включает в себя другие аспекты create-реакции-приложения - которые, опять же, я не использовал - поэтому я отказался от этого.)

Я очень мало знал о внутреннем программировании, прежде чем начал этот процесс.Теперь я прошел курс по node.js и MongoDB (теперь я понимаю, что Mongo не имеет абсолютно никакого отношения к тому, что я пытаюсь сделать).В настоящее время я прохожу курс обучения в Экспрессе, но я все еще в море, и я почти уверен, что у него есть чрезвычайно простое решение.

Я надеюсь, что кто-то может либо: а) объяснить, чтоЯ скучаю;б) направить меня к источнику, который объяснит, но НЕ использует специальную платформу развертывания или приложение создания-реагирования;или в) просто скажите мне одну или две строки кода, которые мне не хватает (я почти уверен, что это будет просто строка или две).

Я создал свой сайт, используя Gulp в качестве моего бегуна задачи все работало отлично локально (например, обновление и прямой доступ к URL-адресу подстраницы, например localhost: 3000 / about сработало).

Код Gulpfile, отвечающий за это:

const browserSync = require('browser-sync');
const historyApiFallback = require('connect-history-api-fallback');

function bs() {
    browserSync.init({
        server: {
            baseDir: './'
        },
        middleware: [historyApiFallback()]
    })
};

ЭтоВозможно, для вас очевидно, что - это мои настройки - попытка прямого доступа к маршрутизации React через URL перестала бы работать, если просто загрузить папку сайта на файловый хост cPanel и ожидать, что она будет работать как локально, но тогдаЯ не знал ничего лучше.

Сейчас я пытаюсь использовать Express для настройки моего файла server.js, чтобы заставить работать одностраничную маршрутизацию приложений.Я уже сказал узлу запустить server.js в моем package.json.Вот как выглядит мой файл server.js:

var express = require('express')
var path = require('path')
var history = require('connect-history-api-fallback');

var app = express()

app.use(history());

app.use(express.static(__dirname))

app.get('*', function (req, res) {

     // I've fiddled with this part a million 
    //different ways but can't seem to get it to work 
    //because including lines like 'alert('WORKING') or 
    //res.alert('WORKING') in here never result in an alert 
    //pop-up when entering a URL

     res.sendFile(path.join(__dirname, '/index.html'))
})

var PORT = process.envPORT || 8080
app.listen(PORT, function() {
    console.log('Production Express server running at localhost: ' + PORT)
})

В конечном итоге я хочу, чтобы URL-адреса, такие как www.mysite.com/about/, загружали страницу и маршрут «/ about» с моего маршрутизатора React, нов этот момент я бы согласился на любые прямые URL-запросы, чтобы просто переслать на www.mysite.com/index, что я тоже пытался и не смог сделать.

Возможно, лучше всего сформулировать ваш ответ, как и выразговариваю с ребенком.

1 Ответ

1 голос
/ 22 мая 2019

Ты сейчас ищешь не в том месте.Помните, что React - это интерфейс между пользователем и браузером (кроме вашей сети распространения контента (cdn), но мы пока не заинтересованы в этом).Ваш сервер взаимодействует с браузером (React).НЕ пользователь.Ваш экспресс-сервер существует для подачи данных в ваш SPA.Маршрутизация контролируется React.

Как вы обнаружили, прямая маршрутизация не работает, потому что технически у вашего веб-сайта есть только один index.html файл, из которого React может работать контрейлер.Это означает две вещи:

  1. React должен иметь возможность интерпретировать различные маршруты
  2. Каждый возможный URL, указанный в вашем домене, должен иметь прямой доступ к index.html.

SPA-маршрутизация с react-router

Для первой проблемы вам нужна явная логика маршрутизации.Именно для этого предназначен пакет npm react-router.

Изменение настроек хоста вашего домена таким образом, чтобы они всегда указывали на index.html, независимо от того, какой URL-адрес пользователь вводит в

. Во-вторых, у вас естьнастроить хост вашего домена для правильной маршрутизации.Если вы посещаете что-либо кроме index.html, вы получаете 404.Вы используете это в своих интересах и настраиваете свой хост для перенаправления 404 прямо на index.html.Это немного на хакерской стороне, но так все и делается (за исключением истории хэшей, о которой мы поговорим позже).enter image description here

Конфигурация обхода хоста и требуется только react-router, с использованием hashHistory

Если вы хотите обойти изменения конфигурации хоста, вы можете использовать react-router s hashHistory вместо browserHistory.Он создает /#/ между вашим доменом и любыми другими маршрутами, что позволяет вам обходить маршрутизацию index.html 404.Недостатком этого является то, что вы получаете «некрасивые» URL.

my-website.com/#/a_route

my-website.com/#/another_route

Удачи

...