Как развернуть «приложение» stati c React в Heroku? - PullRequest
2 голосов
/ 29 марта 2020

Заголовок был: Как исправить ошибку «Невозможно использовать оператор импорта вне модуля» в Heroku, не вызывая ошибку «Необходимо использовать импорт для загрузки модуля ES»?

Это было прежде чем я понял, что пытался развернуть приложение "stati c" React ", и Heroku запускал индекс. js, как будто это был код сервера.

У меня была настройка Procfile для :

web: node ./src/index.js

Затем я увидел эту ошибку:

...
2020-03-29T02:34:01.000000+00:00 app[api]: Build succeeded
2020-03-29T02:34:02.637867+00:00 heroku[web.1]: State changed from starting to crashed
2020-03-29T02:34:02.622526+00:00 heroku[web.1]: Process exited with status 1
2020-03-29T02:34:02.583667+00:00 app[web.1]: /app/src/index.js:1
2020-03-29T02:34:02.583689+00:00 app[web.1]: import React from 'react';
2020-03-29T02:34:02.583690+00:00 app[web.1]: ^^^^^^
2020-03-29T02:34:02.583690+00:00 app[web.1]:
2020-03-29T02:34:02.583691+00:00 app[web.1]: SyntaxError: Cannot use import statement outside a module
2020-03-29T02:34:02.583691+00:00 app[web.1]: at wrapSafe (internal/modules/cjs/loader.js:1072:16)
...

Я попытался исправить это, добавив это в package.json:

  "type": "module",

И затем я получил эту ошибку:

...
2020-03-29T03:05:01.000000+00:00 app[api]: Build succeeded
2020-03-29T03:05:06.293573+00:00 heroku[web.1]: Starting process with command `node ./src/index.js`
2020-03-29T03:05:08.744086+00:00 heroku[web.1]: State changed from starting to crashed
2020-03-29T03:05:08.724957+00:00 heroku[web.1]: Process exited with status 1
2020-03-29T03:05:08.650103+00:00 app[web.1]: internal/modules/cjs/loader.js:1174
2020-03-29T03:05:08.650125+00:00 app[web.1]: throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
2020-03-29T03:05:08.650126+00:00 app[web.1]: ^
2020-03-29T03:05:08.650126+00:00 app[web.1]:
2020-03-29T03:05:08.650126+00:00 app[web.1]: Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /app/src/index.js
2020-03-29T03:05:08.650127+00:00 app[web.1]: at Object.Module._extensions..js (internal/modules/cjs/loader.js:1174:13)
2020-03-29T03:05:08.650127+00:00 app[web.1]: at Module.load (internal/modules/cjs/loader.js:1002:32)
...

Я должен был заметить, что мое "приложение" React является только внешним интерфейсом, использующим API GraphQL, который я уже развернул в другом месте. Другими словами, не существует «сервера. js, который обслуживает [мое] реагирующее приложение». (Комментарий HMR привел меня к этому пониманию. Я думаю, правильной терминологией было бы называть это «stati c app».)

Этот код только в server.js слегка адаптировано из Tin Nguyen ответ работает:

const http = require('http');
const path = require('path');
const express = require('express');

let wss;
let server;
const app = express();
app.use(express.static(path.join(__dirname, './build')));

server = new http.createServer(app);

server.on('error', err => console.log('Server error:', err));
server.listen(process.env.PORT);

... с этим Procfile:

web: node ./server.js

Единственное изменение - путь к каталог сборки, который я подправил после слежки с heroku run bash.

Мой сайт не работает должным образом, но я думаю, что это результат моей сборки не правильно. Возможно, это можно решить с помощью buildpack. Но это относится к другому вопросу. (И я, возможно, не удосуживаюсь выяснить это, поскольку планирую воспользоваться советом Тин Нгуен и попробовать хостинг на GitHub.)

Обновление : проблема была не в моей сборке, а в клиенте маршрутизация на стороне (как описано в https://create-react-app.dev/docs/deployment/). Этот код (с этой страницы) исправляет его (в server.js):

const express = require('express');
const path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'build')));

app.get('/*', function (req, res) {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

app.listen(process.env.PORT);

Ссылка в комментарии HMR помогла мне достичь этого понимания, но Дэйв Седдиа пишет, что его статья рассказывает о том, как сохранить приложение React и сервер API вместе. Есть ли документация о том, как развернуть интерфейс на Heroku (или в другом месте) с сервером API, уже развернутым в другом месте?

(я нашел этот ответ , где Paras рекомендует Netlify .)

Ответы [ 2 ]

3 голосов
/ 02 апреля 2020

Если я правильно понял, у вас есть веб-сайт c и вы хотите, чтобы он был размещен на Heroku.

* * Статистические веб-сайты c могут обслуживаться на страницах Netlify, а также на страницах GitHub. Им не требуется веб-сервер. Вы по-прежнему можете разместить его в Heroku, обернув вокруг него веб-сервер, который затем обслуживает ваши stati c файлы.

const http = require('http');
const path = require('path');
const express = require('express');

let wss;
let server;
const app = express();
app.use(express.static(path.join(__dirname, './../build')));

server = new http.createServer(app);

server.on('error', err => console.log('Server error:', err));
server.listen(process.env.PORT);

Как узнать, есть ли у вас сайт stati c?
Вы должны были сгенерировать файлы сборки где-нибудь в вашем проекте. Вы можете перейти к папке и открыть index.html. Сайт должен работать, даже если у вас не работает node или npm. Эта папка в моем примере ./../build.

Лично я бы порекомендовал вам разместить на GitHub веб-сайты stati c через Heroku. Heroku «свободен», но имеет множество ограничений. Время работы динамо ограничено, веб-сайты должны раскручиваться после долгого неиспользования и т. Д. c.

3 голосов
/ 01 апреля 2020

попробуйте изменить команду:

node ./src/index.js

на:

node --experimental-modules ./src/index.js

Попробуйте как с исправлением пакета, так и без него. json с

"type": "module"
...