Заголовок был: Как исправить ошибку «Невозможно использовать оператор импорта вне модуля» в 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 .)