본 포스트에서는 Front-end는 리액트, Back-end는 Express 기반의 Node.js를 사용하여 하나의 프로젝트로 간단한 Application을 구성해 보겠습니다. 구성할 Application은 이전 포스트에서 진행했던 네이버 API 조회 Application을 재사용 하겠습니다.

 

 

React + Express + TypeScript 프로젝트 구성하기

 

이전 포스트에서는 expressServer 프로젝트 아래 uiModule 이라는 경로를 생성하고 해당 경로를 React 프로젝트로 구성한 후 소스코드를 컴파일 및 번들링해서 Node.js 서버에서 실행해보는 부분까지 진행해 보았습니다. 이번 포스트에서는 이전 포스트들에서 만든 서버 API에서 응답하는 데이터를 확인해 보고, Front-end에서 사용할 데이터 타입을 선언해 보겠습니다.

 

먼저 서버 API의 데이터 구조를 정의한 포스트는 아래 주소를 참고합니다.

React + Express + Typescript - 02. 데이터 타입 선언 :: 즐거운인생 (tistory.com)

 

React + Express + Typescript - 02. 데이터 타입 선언

본 포스트에서는 Front-end는 리액트, Back-end는 Express 기반의 Node.js를 사용하여 하나의 프로젝트로 간단한 Application을 구성해 보겠습니다. 구성할 Application은 이전 포스트에서 진행했던 네이버 API

redballs.tistory.com

 

먼저 로컬 서버를 구동하고 http://localhost:8001/search/news/React 로 접근해서 데이터를 확인해 보겠습니다.

 

HTTP 응답

HTTP 응답은 아래와 같은 형태로 응답코드, 응답메시지, 응답데이터가 return 됩니다.

HTTP 응답

 

DATA 영역

HTTP 응답 중 데이터 영역은 아래와 같이 출력 건수(display), 시작건수(start), 전체건수(total), 검색유형(type), 검색 결과 데이터(items) 가 return 됩니다.

데이터부 응답

 

검색 결과 데이터 영역

검색 결과 데이터 영역은 두 가지 형태로 return 됩니다. type이 news일 경우에는 뉴스 데이터의 배열 형태로 return 되고, type이 book일 경우에는 도서 데이터의 배열 형태로 return 됩니다.

 

[type이 new일 경우]

뉴스 유형의 검색 결과

[type이 book일 경우]

도서 유형의 검색 결과

 

데이터 타입 선언

위 데이터를 분석해서 데이터 타입을 정의하면 되는데, 기본적으로는 서버 애플리케이션에서 정의한 데이터와 동일하게 정의하면 됩니다. 서버 애플리케이션의 정의를 참조하여 아래 경로에 프로그램을 작성합니다.

- ./uiModule/src/interface/apidata.interface.ts

 

먼저 HTTP 응답은 아래와 같이 작성합니다.

interface IHttpResp {
    code: string;
    message: string;
    data: IRespData | null
}

 

서버 요청에 대한 응답은 기본적으로 응답코드와 메시지, 조회한 데이터를 응답하도록 하고 조회한 데이터는 IRespData 형태로 아래와 같이 정의합니다. 오류일 경우 데이터가 없을 수도 있으니 null도 허용해줍니다.

interface IRespData {
    lastBuildDate: string;
    total: number;
    start: number;
    display: number;
    type: string;
    items: INewsData[] | IBookData[];
}

 

Naver API에서 주는 응답의 형태에 현재 데이터의 유형을 구분할 수 있는 type 속성을 추가합니다. 실제 조회한 데이터는 뉴스 데이터일 경우 INewsData의 배열 형태, 도서 데이터일 경우 IBookData의 배열 형태로 구성합니다. INewsData와 IBookData의 정의는 아래와 같습니다.

interface INewsData {
    title: string;
    originallink: string;
    link: string;
    description: string;
    pubDate: string;
}

interface IBookData {
    title: string;
    link: string;
    image: string;
    author: string;
    price: string;
    discount: string;
    publisher: string;
    pubdate: string;
    isbn: string;
    description: string;
}

 

다른 모듈에서 사용할 수 있도록 export를 추가합니다.

export {
    IHttpResp,
    IRespData,
    INewsData,
    IBookData
}

 

JSON 형태로 보면 아래와 같은 형태입니다.

{
    "code": "",
    "message": "",
    "data": {
        "start": 0,
        "total": 0,
        "display": 0,
        "lastBuildDate": "",
        "type": "",
        "items": [{
            "title": "",
            "description": "",
            "link": "",
            "originallink": "",
            "pubDate": ""
        }]
    }
}

 

데이터 타입 선언 부분은 서버와 클라이언트가 동일한 형태로 데이터를 참조해야 하므로 서버 개발자와 클라이언트 개발자가 별개로 있다면 협의해서 인터페이스 하는데 문제 없이 맞추어 가야합니다.

 

다음 포스트에서는 서버에서 제공한 API와 인터페이스하여 선언한 데이터 타입으로 바인드해서 확인해 보겠습니다.

300x250

본 포스트에서는 Front-end는 리액트, Back-end는 Express 기반의 Node.js를 사용하여 하나의 프로젝트로 간단한 Application을 구성해 보겠습니다. 구성할 Application은 이전 포스트에서 진행했던 네이버 API 조회 Application을 재사용 하겠습니다.

 

 

React + Express + TypeScript 프로젝트 구성하기

 

저번 포스트까지 Node.js 서버를 express 기반으로 구성한 후 간단하게나마 서버 프로그램을 작성해서 Naver API를 호출하는 API를 작성하고 테스트 해보았습니다. 이번 포스트에서는 해당 API를 사용하여 UI를 구성할 React 프로젝트의 환경을 구성해 보겠습니다.

 

서버와 클라이언트 프로젝트는 별도의 Repository로 구성해도 되고, 하나의 통합 Repository로 구성해도 됩니다. 여기서는 별도의 프로젝트로 구성하지 않고 express 프로젝트 안에 uiModule이라는 경로를 생성하여 React 프로젝트를 구성해 보도록 하겠습니다.

 

먼저 expressServer 프로젝트의 루트 경로에 uiModule이라는 경로를 생성합니다.

D:\workspace\expressServer> mkdir uiModule
D:\workspace\expressServer> cd uiModule
D:\workspace\expressServer\uiModule>

 

yarn init 명령으로 package.json 파일을 생성합니다.

D:\workspace\expressServer\uiModule> yarn init -y

 

다음은 React 프로젝트에서 사용할 모듈을 설치합니다.  프로젝트에 사용할 모듈에 대한 설명은 아래 포스트를 참고합니다.

React 기초 (목록 - TypeScript) 02 - 프로젝트 생성 :: 즐거운인생 (tistory.com)

 

React 기초 (목록 - TypeScript) 02 - 프로젝트 생성

본 포스트에서는 리액트와 타입스크립트를 이용하여 네이버 API로 데이터를 검색해서 목록 화면을 구성해 보겠습니다. 이전 포스트에서 개발할 내용을 확인해 보았으니, 이제 개발에 필요한 환

redballs.tistory.com

 

설치할 모듈은 아래와 같습니다.

D:\workspace\expressServer\uiModule> yarn add react@17.0.2
D:\workspace\expressServer\uiModule> yarn add react-dom@17.0.2
D:\workspace\expressServer\uiModule> yarn add --dev babel-core@6.26.3
D:\workspace\expressServer\uiModule> yarn add --dev babel-loader@8.2.3
D:\workspace\expressServer\uiModule> yarn add --dev babel-preset-react-app@10.0.1
D:\workspace\expressServer\uiModule> yarn add --dev webpack@5.66.0
D:\workspace\expressServer\uiModule> yarn add --dev webpack-cli@4.10.0
D:\workspace\expressServer\uiModule> yarn add --dev typescript
D:\workspace\expressServer\uiModule> yarn add --dev @types/react @types/react-dom
D:\workspace\expressServer\uiModule> yarn add moment@2.29.1

 

위 포스트에서 사용했던 webpack-dev-server는 이미 express로 구성한 서버가 있으므로 설치하지 않습니다.

 

/uiModule/src 경로를 생성하고, 아래와 같이 main.tsx 파일을 작성합니다

import ReactDOM from 'react-dom';

ReactDOM.render(<div>Hello World</div>, document.getElementById('app'));

 

타입스크립트를 사용하도록 tsx 파일로 생성했으므로 uiProject 하위에 tsconfig.json 파일을 아래와 같이 생성합니다.

{ 
    "compilerOptions": {
        "jsx": "react-jsx",
        "target": "es6",
        "module": "commonjs",
        "outDir": "./dist",
        "rootDir": "./src",
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true
    }
}

 

rootDir 이 ./src 이므로 uiModule/src 하위 파일들에 대해 컴파일을 수행하고 outDir 이 ./dist 이므로 uiModule/dist 하위에 컴파일 결과 파일을 생성합니다.

 

 

uiModule 의 package.json 파일에 build 스크립트를 아래와 같이 추가합니다.

{
  "name": "uiModule",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "moment": "2.29.1",
    "react": "17.0.2",
    "react-dom": "17.0.2"
  },
  "devDependencies": {
    "@types/react": "^18.0.15",
    "@types/react-dom": "^18.0.6",
    "babel-core": "6.26.3",
    "babel-loader": "8.2.3",
    "babel-preset-react-app": "10.0.1",
    "typescript": "^4.7.4",
    "webpack": "5.66.0",
    "webpack-cli": "4.10.0",
    "webpack-dev-server": "4.7.3"
  },
  "scripts": {
    "build": "webpack"
  }
}

 

여기까지 작업을 하면 uiModule 하위의 프로젝트 구조는 아래와 같습니다.

uiModule 프로젝트 구조

 

이제 tsc 명령으로 컴파일을 하면 아래 그림과 같이 dist 폴더가 생성되고 그 하위에 컴파일 결과가 생성됩니다.

D:\workspace\expressServer\uiModule> tsc

컴파일 결과 생성 확인

 

여기까지 잘 되었다면 이제 Node.js 서버에서 uiModule을 사용하기 위해 expressServer 프로젝트의 /public/js 하위로 컴파일 결과 파일들을 번들링하기 위해 아래와 같이 uiModule/webpack.config.js 파일을 생성합니다.

'use strict'
const path = require('path');

module.exports = {
    entry: {
        main: ['./dist/main.js']
    },
    output: {
        path: path.resolve(__dirname, '../public/js'),
        filename: 'build.js'
    },
    module: {
        rules: [{
            test: /\.jsx?$/,
            use: {
                loader: 'babel-loader'
            }
        }]
    }
};

 

애플리케이션의 시작점은 ./dist/main.js 로 컴파일 되므로 entry는 main.js 로 설정합니다. 번들링한 결과는 uiProject 외부에 있는 프로젝트 루트의 ./public/js로 전송해야 하므로 output은 위와 같이 설정하고 번들링한 결과는 build.js로 생성합니다.

D:\workspace\expressServer\uiProject> npm run build

 

npm run build 명령으로 번들링하면 아래 그림과 같이 결과가 생성됩니다.

번들링 결과 확인

 

번들링한 결과를 사용할 수 있도록 아래와 같이 index.html 파일을 수정합니다.

<!DOCTYPE html>
<html>
    <head>
        <title>Express Sample</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    </head>
    <body>
        <div id="app"></div>
        <script type="text/javascript" src="js/build.js"></script>
    </body>
</html>

 

이제 프로젝트 루트로 이동해서 yarn start 명령으로 서버를 실행시키고 화면에 Hello World가 표시되는지 확인합니다.

D:\workspace\expressServer> yarn start

 

 

실행 결과 확인

300x250

+ Recent posts