Express와 React 연동 (with Typescript)

김희윤·2021년 3월 30일
2

react

목록 보기
4/4

0. React 서버 랜더링

Vue.js는 Express와 연동한 경험이 있었지만 React는 해본 적이 없어서 물론 비슷하겠지만 궁금증이 생겨 공부하고 진행했다.

1. CRA(Create-React-App)으로 React 프로젝트 생성

npx create-react-app client --template typescript

명령어로 client란 이름의 React 프로젝트를 생성한다.

React with Typescript 설정방법 을 따라서 설정을 완료한다.

yarn start

로 실행하면 기본화면이 잘 뜸을 볼 수 있다.

  • 서버에서 사용하기 위해서 build를 한다.
yarn build

그럼 아래와 같이 build 폴더가 생긴다.

2. Express server 생성

root 주소로 나와서

mkdir server

명령어로 server 코드를 사용할 폴더를 생성한다.

그럼 이런 모습이 된다. (markdown_img는 README.md에 사용한 폴더이기 때문에 무시하면 된다.)
.

Typescript를 사용할 것이기 때문에 React와 같이 설정을 한다. 하지만 조금 다르기 때문에 코드를 새로 올렸다.

- tsconfig.json

{    
  "compilerOptions": {        
      "module": "commonjs",
      "esModuleInterop": true,        
      "target": "es6",
      "noImplicitAny": true,        
      "moduleResolution": "node",        
      "sourceMap": true,
      "outDir": "dist",        
      "baseUrl": ".",        
      "paths": {
          "*": [
              "node_modules/*",
              "src/types/*"            
          ]
      }  
  },
  "include": [ "src/**/*" ],
  "exclude": [ "src/public" ]
}

- .eslintrc.js

// .eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
  ],
  plugins: ['prettier', '@typescript-eslint'],
  rules: {
    'prettier/prettier': [
      'error',
      {
        singleQuote: true,
        semi: true,
        useTabs: false,
        tabWidth: 2,
        printWidth: 80,
        bracketSpacing: true,
        arrowParens: 'avoid',
      },
    ],
  },
  parserOptions: {
    parser: '@typescript-eslint/parser',
  },
};

- .prettierrc

{
  "singleQuote": true,
  "parser": "typescript",
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "printWidth": 120,
  "arrowParens": "always"
}
  • code를 작성할 src 파일을 제작하고 안에 express를 사용할 index.ts, public 폴더, routes 폴더, views 폴더, types 폴더를 작성한다.

  • routes, views 안에 각각 기본라우터와 기본 뷰인 index.ts, index.ejs를 만든다.
    (index.ejs는 서버가 작동하는지만 확인하고 안쓸 예정)

그럼 아래 사진과 같은 모습이 된다.

- /src/index.ts를 아래와 같이 작성하고 모듈들을 다운 받는다.

import express from 'express';
import createError from 'http-errors';
import path from 'path';
import cookieParser from 'cookie-parser';
import logger from 'morgan';
import session from 'express-session';
import cors from 'cors';
import FileStore = require('session-file-store');
const useFileStore = FileStore(session);

// Routing
import { indexRouter } from './routes/index';

// PORT
const app = express();
const PORT = 3001; // React가 기본으로 3000번을 사용해서 다른 포트를 사용해야 함.

// View Engines
app.set('views', path.join(__dirname, '../../client/build'));
app.set('view engine', 'ejs');

app.use(cors());
app.use(
  session({
    secret: 'omniapwd',
    resave: false,
    store: new useFileStore(),
    cookie: {
      httpOnly: false,
      secure: false,
      maxAge: 1200000,
    },
  })
);
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '../../client/build'))); // css, ts 파일을 사용할 폴더 위치

// Routing
app.get('/', indexRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err: any, req: any, res: any, next: any) {
  // 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');
});

// start server at 3001
app.listen(PORT, () => {
  console.log(`⚡️[server]: Server is running at https://localhost:${PORT}`);
});

module.exports = app;

- views/index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>Typescript Expressjs Server!
  </h1>
  <p>lalalal sinnanda</p>
</body>
</html>

- src/routes/index.ts

import express from 'express';
import path from 'path';
export const indexRouter = express.Router();

indexRouter.get('/', (req, res) => {
  res.render('index');
});

- package.json (아래 부분으로 수정한다.)

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "prestart": "tsc",
    "start": "nodemon --exec ts-node dist/index.js"
  },
yarn start

를 누르면 다음과 같이 뜨고

http://localhost:3001로 들어가면

React의 화면이 서버로 실행됨을 볼 수 있다.

profile
블록체인, IOT, 클라우드에 관심이 많은 개발자 지망생

0개의 댓글