인프런 커뮤니티 질문&답변

김명재님의 프로필 이미지
김명재

작성한 질문수

[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지

redis에 세션 저장하기

pm2 error

작성

·

505

0

const express = require("express");
const cookieParser = require("cookie-parser");
const morgan = require("morgan");
const session = require("express-session");
const router = express.Router();
const path = require("path");
const dotenv = require("dotenv");
const passport = require("passport");
const app = express();
const passportConfig = require("./passport");
const redis = require("redis");
const RedisStore = require("connect-redis").default;

dotenv.config();

const redisClient = redis.createClient({
  url: `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`,
  password: process.env.REDIS_PASSWORD,
  legacyMode: false,
});
redisClient.connect().catch(console.error);

const authRouter = require("./routes/auth");
const pageRouter = require("./routes/page");
const postRouter = require("./routes/post");
const userRouter = require("./routes/user");
const commentRouter = require("./routes/comment");
const updateRouter = require("./routes/update");
const deleteRouter = require("./routes/delete");
const helmet = require("helmet");
const hpp = require("hpp");
const { sequelize } = require("./models");
const logger = require("./logger");

passportConfig();
app.set("port", process.env.PORT || 8005);

sequelize
  .sync({ force: false })
  .then(() => {
    console.log("데이터베이스 연결 성공");
  })
  .catch((err) => {
    console.error(err);
  });

if (process.env.NODE_ENV === "production") {
  app.use(
    helmet({
      contentSecurityPolicy: false,
      crossOriginEmbedderPolicy: false,
      crossOriginResourcePolicy: false,
      crossOriginOpenerPolicy: false,
      originAgentCluster: false,
    })
  );
  app.use(hpp());
  app.use(morgan("combined"));
} else {
  app.use(morgan("dev"));
}
app.use(express.json({ limit: "10mb" }));
var cors = require("cors");
const { deepStrictEqual } = require("assert");
app.use(cors());
app.use("/img", express.static(path.join(__dirname, "uploads")));
app.use("/profileImg", express.static(path.join(__dirname, "profileImg")));
app.use(express.json());
app.use(express.urlencoded({ limit: "10mb", extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
const sessionOption = {
  resave: false,
  saveUninitialized: false,
  secret: process.env.COOKIE_SECRET,
  cookie: {
    httpOnly: true,
    secure: false,
  },
  store: new RedisStore({ client: redisClient }),
};
if (process.env.NODE_ENV === "production") {
  sessionOption.proxy = true;
}
app.use(session(sessionOption));

app.use(passport.initialize());
app.use(passport.session());


app.use(express.static(path.join(__dirname, "prototype-client/build")));

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "prototype-client/build/index.html"));
});

app.use("/page", pageRouter);
app.use("/auth", authRouter);
app.use("/post", postRouter);
app.use("/user", userRouter);
app.use("/comment", commentRouter);
app.use("/update", updateRouter);
app.use("/delete", deleteRouter);

//react에서 react-router-dom으로 다룰 수 있게
app.get("*", function (req, res) {
  res.sendFile(path.join(__dirname, "/prototype-client/build/index.html"));
});


//에러 처리 담당
app.use((req, res, next) => {
  const error = new Error(`${(req, method)} ${req.url} 라우터가 없습니다.`);
  error.status = 404;
  logger.info("hello");
  logger.error(error.message);
  next(error);
});

app.use((err, req, res, next) => {
  console.error(err);
  res.locals.message = err.message;
  res.locals.erorr = process.env.NODE_ENV !== "production" ? err : {};
  res.status(err.status || 500);
  res.render("error");
});

module.exports = app;

이렇게 코드를 실행하면 sudo pm2 monit의 server log에 2가지 에러가 나옵니다.


server > [Error: ENOENT: no such file or directory, stat

│ ││ server > errno: -2,

│ ││ server > code: 'ENOENT',

│ ││ server > syscall: 'stat',

│ ││ server > path: '/home/bitnami/Whats-up/prototype-client/bu │

│ ││ server > expose: false,

│ ││ server > statusCode: 404,

│ ││ server > status: 404

│ ││ server > }

에러 메시지를 봤을때 해당 경로에 대한 파일을 찾을 수 없다고 하는데 ls를 입력했을때 잘 있는걸 확인 할 수 있는데 왜 이런 에러가 발생하는지 모르겠습니다..
스크린샷 2023-11-21 오후 5.29.27.png

2번쨰는
server > Error: No default engine was specified and no

││ server > at new View (/home/bitnami/Whats-up/node_module │

││ server > at Function.render (/home/bitnami/Whats-up/node │

││ server > at ServerResponse.render (/home/bitnami/Whats-u │

││ server > at /home/bitnami/Whats-up/app.js:127:7 │

││ server > at Layer.handle_error (/home/bitnami/Whats-up/n │

││ server > at trim_prefix (/home/bitnami/Whats-up/node_mod │

││ server > at /home/bitnami/Whats-up/node_modules/express/

││ server > at Function.process_params (/home/bitnami/Whats

이런 에러가 발생합니다. 에러 메세지를 봤을떄는 view engine관련된 에러같은데 react랑 express연동할때는 따로 view engine 설정을 주지 않고 express.static으로 리액트 코드를 전달하면 되는거 아닌가요?

답변 2

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

ls /home/bitnami/Whats-up/prototype-client/build/index.html

해보세요

김명재님의 프로필 이미지
김명재
질문자

감사합니다..선생님
ls 해서 build파일이 있는지 없는지 확인했더라면 좋았을텐데... 당연히 github에 잘 올라갔는줄 알고 ls할 생각을 못했네요... gitignore에 /build가 있었습니다. 정말 감사합니다

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

res.render를 사용하면 view engine 에러가 발생합니다. res.render가 아니라 res.sendFile로 index.html을 주셔야 합니다.

김명재님의 프로필 이미지
김명재
질문자

답변 감사합니다.
그런데


app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "/prototype-client/build/index.html")); }); app.use("/page", pageRouter); app.use("/auth", authRouter); app.use("/post", postRouter); app.use("/user", userRouter); app.use("/comment", commentRouter); app.use("/update", updateRouter); app.use("/delete", deleteRouter); //react에서 react-router-dom으로 다룰 수 있게 app.get("*", function (req, res) { res.sendFile(path.join(__dirname, "/prototype-client/build/index.html")); });

이 코드를 실행하고 보면

아래와 같은 에러가 발생합니다.
server > [Error: ENOENT: no such file or directory, stat │

│ ││ server > errno: -2,

│ ││ server > code: 'ENOENT',

│ ││ server > syscall: 'stat',

│ ││ server > path: '/home/bitnami/Whats-up/prototype-client/build/s │

│ ││ server > expose: false,

│ ││ server > statusCode: 404,

│ ││ server > status: 404

│ ││ server > }
이 에러가 왜 발생하는지 도저히 이해가 안됩니다.. 로컬에서는 분명히 잘 실행 되었습니다..
혹시 문제를 해결할만한 힌트라도 주실 수 있으신가요?..

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

build/s 라고 나오는데 s가 뭔 파일인가요?

김명재님의 프로필 이미지
김명재
질문자

아 저게 에러에 원래 build/i 밖에 안나와서 뭔가 이상해서 테스트 좀 해본다고

app.get("/", (req, res) => {   res.sendFile(path.join(__dirname, "/prototype-client/build/index.html")); }); 

에서 index.html을 잠시 sdex.html로 고치고 실행해본건데 원래는 build/i라고 나옵니다. 제 생각에는 칸수가 안되서 i까지 밖에 안나오는 것 같습니다

김명재님의 프로필 이미지
김명재

작성한 질문수

질문하기