Ситуация:
Я создаю веб-приложение (SPA) с ReactJS и ExpressJS. Я использую Socket.IO для общения в реальном времени. Когда я создаю свое приложение и запускаю его на локальном хосте, все работает нормально, поэтому я решаю развернуть его на Heroku. Мое приложение успешно построено на Heroku и готово к использованию.
Проблема:
Поэтому я захожу в свое приложение, чтобы посмотреть, нормально ли оно работает на Heroku. Кажется, что с приложением все в порядке, когда я захожу на страницу входа и страницу регистрации (эти страницы не идут с Socket.IO). Но когда я перехожу на страницу чата (эта страница использует Socket.IO для общения в реальном времени), клиент аварийно завершает работу, он не загружается и выдает следующую ошибку.
Ошибка:
Я получаю следующую ошибку:
> Uncaught TypeError: Cannot read property 'DEBUG' of undefined
at load (browser.js:168)
at Object.eval (browser.js:178)
at eval (browser.js:197)
at Object../node_modules/socket.io-client/node_modules/debug/src/browser.js (vendor.js:2639)
at __webpack_require__ (main.js:788)
at fn (main.js:151)
at eval (url.js:7)
at Object../node_modules/socket.io-client/lib/url.js (vendor.js:2628)
at __webpack_require__ (main.js:788)
at fn (main.js:151)
Когда я смотрю на модуль онлайн, у него есть следующая проверка:
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = undefined.DEBUG; //the error is showed here
}
Итак, я запускаю свое приложение на локальном хосте и ищу приведенный выше код, я получаю следующее:
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = { /*A JSON object contains .env variables*/ }.DEBUG;
}
Код:
Это мой сервер:
//requirements...
const socket = require("./server/socket");
const app = express();
const server = http.createServer(app);
const port = process.env.PORT || 3000;
//middlewares...
//routes...
//database connection...
socket(server);
server.listen(port);
console.info("Server started on: " + port);
Моя настройка сокета:
const socketIO = require("socket.io");
const socket = server => {
const io = socketIO(server);
const chat = io.of("/chat");
chat.on("connection", client => {
console.info("User started chat!");
client.on("disconnect", () => {
console.info("User left chat!");
});
client.on("sendMessage", msg => {
const data = msg;
client.broadcast.emit("incomingMessage", { data });
});
});
};
module.exports = socket;
Компонент React, использующий Socket.IO:
const _ChatBox = ({ props }) => {
const [connection] = useState(io("/chat"));
useEffect(() => {
connection.on("incomingMessage", message => {
//receive message...
});
}, []);
const sendMessageToSocket = data => {
connection.emit("sendMessage", data);
};
return (
/* JSX here */
);
};
Что я хочу:
Я хочу знать, есть ли какие-либо проблемы с моим кодом. Когда я развертываю свое приложение в Heroku, нужно ли мне выполнять какие-либо дополнительные настройки в Heroku, чтобы мое приложение работало с Socket.IO?
@VaughanHilts клиент
Проблема не в коде, который вы вставили, или, по крайней мере, я в этом сомневаюсь. Если вы посмотрите на модуль онлайн, вы увидите, что он имеет следующую проверку:
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = process.env.DEBUG;
}
Вы заметите, что он считывает это process.env
, это вещь Node / вещь Electron. Внутри консоли вашего клиента введите window.process
, если вы что-то получили, возможно, это оно. Он проверяет process
... возможно, веб-пакет
Я получаю это r = undifined.DEBUG;
вместо r = process.env.DEBUG;
Для window.process
?
да, когда я набираю window.process
, он возвращает undefined
Потратив несколько часов на изучение и просмотр своего кода, я понял, почему мое приложение не работает на Heroku. Это потому, что клиент использует модуль dotenv
, а я настроил его в webpack.config.js
:
//...requirements
const dotenv = require("dotenv");
const webpack = require("webpack");
module.exports = {
//...configs
plugins: [
//...other plugins
new webpack.DefinePlugin({
"process.env": JSON.stringify(dotenv.parsed)
})
]
};
Затем, когда я разверну свое приложение на Heroku, Heroku соберет мой клиент из исходного кода, а сервер будет искать интерфейсную часть в папке dist
. Клиент теперь не может найти файл .env
на Heroku, поэтому он не может загрузить переменные среды, из-за которых он выдает ошибку.
Я удалил dotenv
, потому что он мне сейчас не нужен.
Что рушится? Сервер или клиент?