#reactjs #express #plesk
Вопрос:
БОЛЬШОЕ РЕДАКТИРОВАНИЕ, ТАК КАК Я ПРОВЕЛ ЕЩЕ НЕСКОЛЬКО ИССЛЕДОВАНИЙ
Я пытаюсь развернуть свое первое приложение Nodejs/React на облачном сервере с помощью Plesk.
Вот что я попробовал сначала: я создал файл .httaccess со следующим содержимым.
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
Проблема с этим заключалась в том, что у меня не было доступа к экспресс-app.js больше, так как реагирует index.html файл обрабатывает все. Таким образом, альтернативой является соответствующий маршрут из app.js из «экспресса». Я нашел следующий подход и пытаюсь его реализовать.
Приблизиться:
/api/app.js
app.use('/result', resultRouter);
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
Моя реализация:
var createError = require('http-errors');
var express = require('express');
const cors = require('cors');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
require('dotenv').config();
var helmet = require('helmet');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var resultRouter = require('./routes/result');
var app = express();
app.use(helmet());
app.use(cors());
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
next();
});
//Set up mongoose connection
var mongoose = require('mongoose');
var mongoDB = 'MYMONGODBURL';
mongoose.connect(mongoDB, { useNewUrlParser: true, useUnifiedTopology: true });
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/result', resultRouter);
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});
app.get('*', function (req, res) {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Хотя я уверен, что в целом это правильное решение, мне не удается его реализовать. The app.js файл лежит в папке api. Перед загрузкой в Plesk я вставляю папку сборки изнутри react. Таким app.js
образом, и build
папка находятся на одном уровне каталога.
После загрузки через git у меня есть как корневой каталог документа, так и корневой каталог приложения, установленный в конфигуратор/api. Конфигуратор-это просто пустая папка, которую я настроил заранее.
Если я установлю корень документа в конфигуратор/api/сборка, начальная страница моей реакции index.html отобразится файл. Но маршрутизация к любому другому компоненту react не работает.
Что я здесь делаю не так? Также я включил «поиск домена«, но все равно получаю ошибку тайм-аута шлюза 504.
Я надеюсь, что кто-нибудь сможет указать мне правильное направление или внесет свой вклад в то, куда мне следует смотреть дальше.
Заранее спасибо
Комментарии:
1. Обновил свой вопрос, так как я провел еще несколько исследований, и мой первый подход оказался тупиковым.
2. Также: Мой пакет.json устанавливает начальную точку в /bin/www. Должен ли я поместить его в узел app.js вместо этого?
Ответ №1:
Нашел решение своей проблемы.
Поэтому я знаю, что мой вопрос находится на самом начальном уровне, и оглядываясь назад, я не дал достаточно информации, чтобы кто-то помог мне здесь. Но я нашел решение, которое, надеюсь, поможет другим новичкам, застрявшим на этом этапе. Поэтому я пишу, чтобы поделиться тем, что я узнал в процессе, а также поразмышлять над этим.
2 способа получить реакцию/экспресс-запуск на Plesk
В принципе, есть два способа заставить react/express работать на Plesk. Оба решения жизнеспособны, но решают различные предварительные задачи.
Решение 1. Вы хотите визуализировать статический сайт с помощью react, который не выполняет никаких внутренних запросов к nodejs.
В этом случае вы запускаете ǹpm run build
в своей папке react и помещаете вновь созданную папку сборки в папку express. Внутри папки сборки создайте файл .htaccess со следующим содержимым:
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
Я думаю, что, делая это таким образом, вам даже не нужны nodejs. Но я еще не пробовал этого. В любом случае. Загрузите папку (назовем ее api) в Plesk через git и установите корень документа в api/build, в то время как корень приложения-это просто api.
Решение 2.Вы хотите визуализировать статическую реакцию, но в любой момент выполняете внутренние запросы для выражения какой-либо бизнес-логики или запросов к базе данных.
Как и в решении 1, создайте папку сборки и переместите ее в папку api. Папка сборки-это все, что вам нужно от React, чтобы ваше приложение работало в конце. В папке api создайте новый файл Javascript на корневом уровне. Назови это server.js. Внутри поместите следующий код:
const app = require('./app');
const http = require('http');
http.createServer(app).listen(process.env.PORT);
Как я понял, это запускает ваш сервер в первую очередь, и без этого вы получите ошибку тайм-аута 504.
Во-вторых, вам нужно сообщить nodejs, что он перенаправляется на реакцию index.html файл, всякий раз, когда вы попадаете на маршрут, который не определен в express. Для этого откройте свой app.js файл. Перейдите прямо под последним из ваших экспресс-маршрутов и вставьте следующее:
app.use('/result', resultRouter);
// ^ above is the last route of my express app.
// below tells your server to redirect all other routes to index.html from React
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});
app.get('*', function (req, res) {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});
После изменения и загрузки в Plesk установите корневой каталог документа и корневой каталог приложения из приложения Plesk-Nodejs в api (или в любой другой корневой папке). Затем установите начальный файл приложения в server.js. Теперь все должно сработать.
Диагностика
Вот некоторые препятствия, с которыми я столкнулся на этом пути, и с которыми вы также можете столкнуться.
- Ошибка политики безопасности контента: После успешной настройки всего с помощью решения 2 я получил ошибку Политики безопасности контента. Это произошло из-за шлема промежуточного программного обеспечения, который я использую в своем экспресс-приложении. Прокомментируйте шлем, чтобы проверить, в чем проблема. Если это так, то есть способы правильно настроить шлем. На самом деле вам не нужно его отключать.
- Ошибка CORS: Мой внутренний запрос не удался из-за нарушения той же политики происхождения. Это было связано с тем, что запрос axios от react к express все еще ссылался на localhost. Замените все URL-адреса запросов axios в React правильным URL-адресом из вашего производственного домена.