관리 메뉴

SIMPLE & UNIQUE

1회차_2강 : node 설치, create react app설치, node express 설치, 디렉터리 구조 설정 (Proxy 정상 동작 확인) 본문

탈잉 강의 자료/react.js(프론트) + node.js(백앤드) 개발에서 배포까지

1회차_2강 : node 설치, create react app설치, node express 설치, 디렉터리 구조 설정 (Proxy 정상 동작 확인)

착한코딩 2019. 11. 5. 14:17

1_2 목표 : create-react-app으로 react 서버를, express로 node 서버를 각각 구동한다. Proxy를 설정한다.
react페이지에서 get/post 방식으로 api를 호출해, node 서버의 json 데이터를 가져온다.

1. node.js 설치

nodejs 공식 사이트에서 최신버전(2019.12.13 기준 13.5.0)이 아닌 이전 버전(12.8.0)을 설치한다.

                      ** 12.8.0 버전은 2019년 8월 버전으로 현재까지 개발하면서 안정적이라고 판단.

 

아래 링크에서 윈도우(64비트)는 node-v12.8.0-x64.msi 파일을

                   Mac은 node-v12.8.0.pkg 파일을 다운로드 한다.

 

https://nodejs.org/download/release/v12.8.0/

 

 

설치확인 : 윈도우는 cmd > node -v로 버전 확인    ( win + r > cmd 실행)

              Mac은 터미널에서 node -v로 버전 확인 ( cmd + space > Spotlight > terminal.app 실행)

2. VS code 설치

https://code.visualstudio.com/

 

3. cmd 또는 터미널을 띄운다

 

4. workspace로 사용할 폴더에 접근한다. 

cd C:\Users\ljung\OneDrive\문서\taling

5. create-react-app 글로벌 설치 후, 프로젝트를 생성한다.

npm : Node Package Mananger의 약어로 개발에 필요한 노드모듈=패키지들을 제공.

        쉽게 다운받아 사용 가능하게 해준다.

yarn : npm 대체제. 페이스북에서 만든 패키지. npm에 비해 가볍고 빠르다. 따로 설치필요.

//글로벌 설치
npm install -g create-react-app

//프로젝트 생성
create-react-app client

react 경로 C:\Users\ljung\OneDrive\문서\taling\client 에서

npm install로 패키지를 설치해주고, npm start로 react 서버 구동확인(http://localhost:3000/)

// package.json에 기술된 패키지를 한꺼번에 설치
npm install 
// 서버실행
npm start

 

6. node express 프레임워크 설치

node 경로 C:\Users\ljung\OneDrive\문서\taling에서 명령어 실행

//express 설치
npm i -g express-generator 
// 프로젝트 생성
express project202001 

project202001폴더 안에있는 파일&폴더들을 상위 경로인

C:\Users\ljung\OneDrive\문서\taling 으로 옮기고 project202001폴더는 삭제한다.

 

폴더 변경 전

폴더 변경 후

react와 node 서버 모두 기본 포트가 3000으로 설정되어 있다.
중복을 피하기 위해, bin/www 파일에서 node 서버의 포트를 5000으로 바꿔준다.

node 경로 > app.js 파일도 react에 동일한 이름의 파일이 있기 때문에 server.js로 파일명을 바꿔준다.

 

//node 경로 > bin/www 파일
var port = normalizePort(process.env.PORT || '3000');//수정전
var port = normalizePort(process.env.PORT || '5000');//수정후

var app = require('../app');//수정전
var app = require('../server');//수정후

npm install로 npm을 설치해주고, node server 로그를 확인하기 위해 nodemon를 설치한다. 

(console.log를 보거나 여러가지 서버 상태를 확인할 수 있다.)

npm start로 node 서버 구동확인(http://localhost:5000/)

// express에 필요한 npm 모듈들을 설치
npm install
// 로그를 보기위해 nodemon 설치
npm install -g nodemon
// 서버 실행
npm start

nodemon : 소스코드가 바뀔 때마다 자동으로 노드를 재실행주는 패키지

 

7. 프록시 추가

  react 경로 C:\Users\PC3\Documents\20191105_PROJECT\client 에서 package.json파일에 프록시를 추가해준다. 

프록시는 react에서 node API를 호출하기 위해 사용하는 것인데, 서버 1대에서 react,node 서버를 모두 구동할 수 있게 해준다.  나중에 실서버 배포시에는 여유가 된다면, 각각 서버 1대씩 할당해주는 것도 좋은 방법이다.

(proxy오류 해결가능)

package.json : 패키지마다 고유 버전이있는데, 설치시점의 버전을 기록해두는 소스.

                    이 파일 덕분에 소스 이동 or 서버배포시 node_modules 폴더안의 모듈파일들을 옮기지 않아도 된다.

                    npm install 명령어 하나로 package.json에 기록된 모듈들을 전부 설치해 주기 때문에.

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-scripts": "3.3.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "proxy": "http://127.0.0.1:5000/"
}

 

React 디렉토리 구현

  React서버의 홈화면 App.js이다. 이제 App.js파일은 react 라우팅 페이지로 사용할 것이다.

매 접속(페이지 새로고침)마다 App.js파일을 거쳐서 페이지가 열리기 때문에

레이아웃(header footer)설정, 사용자 권한 관리 등의 용도로 사용할 것이다.

 

<참고> https://leejungyeoul.tistory.com/70?category=649936

 

1. node 경로는 back-end 서버 역할만 할 것이기 때문에, public과 views폴더는 삭제해준다.

2. view 경로 생성

  react 경로 C:\Users\ljung\OneDrive\문서\taling\client\src에 components 폴더를 생성한다.

react에서는 디폴트 root경로가 src폴더인데, /components가 추가됐으니 코드 수정이 필요하다.

/client/src/index.js 파일을 아래와 같이 수정한다. 

  기존의 내용과 수정된 것은 /components경로가 추가되고, 수정된 경로의 App.js파일을 BrowserRouter로 사용하겠다는 내용이다. 

//client/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { BrowserRouter } from 'react-router-dom';
import App from './components/App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render((
    <BrowserRouter>
        <App />
    </BrowserRouter>
), document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();


App.js 파일은 client/src/components 경로로 옮기고, 아래와 같이 수정한다. 

App.css 파일은 삭제한다.

/Api_test 경로로 유입된 호출 Api_test.js 파일로 이동시킨다는 내용이다.

//client/src/components/App.js
import React, { Component } from 'react';
import { Router, Route, Switch } from "react-router";

import Api_test from './Api_test'

class App extends Component {
  constructor (props) {
    super(props);
    
    this.state = {
    }
}
  componentDidMount() {}
  render () {
    return (
      <div className="App">
          <Switch>
            <Route exact path='/' component={Api_test} /> // root 경로일 경우 라우팅
            <Route path='/Api_test' component={Api_test} />
          </Switch>
      </div>
    );
  }
}

export default App;

페이지간 라우팅을 위해 C:\Users\ljung\OneDrive\문서\taling\client 경로에서

react_router_dom과 react-router를 설치한다.

npm install --save react-router-dom
npm install --save react-router

## 참고 ##

새로운 npm 모듈이 추가될 때 마다, 명령어로 설치한다.
client 경로에 아래 명령어를 실행한다. --save을 써주면 package.json에 기록하면서 설치한다.

(차후에 client/package.json 파일에 모듈정보를 작성해 놓고, npm install 명령어를 실행하면 작성된 모든 모듈을 한번에 설치할 수도 있다.)

 

react-router-dom은 react에서 페이지간 라우팅(경로호출 > 실제 jsx페이지 맵핑), 링크, 리다이렉트 등에 사용되는 모듈이다. 

react-router와 차이점은 react-router-dom이 좀 더 핵심기능만 추려놓은 것이라고 하는데

모듈별 사용했던 기능은 아래와 같다.

 

import { Router, Route, Switch } from "react-router";

import { BrowserRouter, Link, Route, Redirect, Switch  } from 'react-router-dom';

 

 3. http통신(get방식)으로 node Api 호출

 

server.js를 보면 기본적으로 indexRouter와 usersRouter 세팅이 되어있다. react에서 node api를 호출해 proxy가 정상적으로 동작하는지 확인하기 위해서, 이미 세팅되어 있는 usersRouter를 사용하려고 한다.

 

server.js의 불필요한 소스를 삭제하고 아래와 같이 수정한다.

 

var express = require('express');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

app.use('/', indexRouter);
app.use('/users', usersRouter);

module.exports = app;

/routes/users.js 파일을 아래와 같이 수정한다.

response형태를 json으로 수정했다.

//routes/users.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  console.log('user router')
  res.send({'message':'respond with a resource'});
});

module.exports = router;

/src/components/폴더에 Api_test.js파일을 추가한다.

import React, { Component } from 'react';

class App extends Component {
  state = {
    response: '',
  };
  
  //페이지 로드시 실행 GET TEST
  componentDidMount() {
    this.callApi()
      .then(res => this.setState({ response: res.express }))
      .catch(err => console.log(err));
  }
  
  callApi = async () => {
    try {
      const response = await fetch('/users');
      const body = await response.json();
      alert(body.message)
      if (response.status !== 200) throw Error(body.message);
      return body;
    } catch (error) {
      alert(error)
    }
  };
  
render() {
    return (
        <div></div>
    );
  }
}

export default App;

 

 4. cmd 창을 2개 열고 react, node 서버를 각각 실행한다.

cd 명령어로 node 경로 들어가 npm start 명령어로 node 서버를 실행한다.

  cd C:\Users\ljung\OneDrive\문서\taling
  npm start

cd 명령어로 react 경로 들어가 npm start 명령어로 react 서버를 실행한다.

cd C:\Users\ljung\OneDrive\문서\taling\client
npm start

http://localhost:3000/

react 서버에서 아래와 같이 alert이 뜬다면 정상적으로 react 에서 node api를 호출한 것이다.

코드 실행 과정은 아래와 같다.

1) React페이지 경로(http://localhost:3000/Api_test)를 주소창에 입력한다.

2) /client/src/index.js에서 라우팅 설정된 /components/App.js 으로 이동한다.

3) App.js를 읽고 view경로인 /clinet/components에서 /Api_test경로와 매칭되는 Api_test.js을 찾아 이동시킨다.

(App.js 에  import Api_test from './Api_test' 부분)

4) Api_test.js 페이지로 이동해서

componentDidMount() > callApi()가 읽히고,  await fetch('/users'); 이 부분에서 /users경로를 호출한다.

5) server.js /users와 일치하는 경로가 매칭된다. /routes/users.js 파일을 찾아 이동시킨다.

var usersRouter = require('./routes/users');
app.use('/users', usersRouter);

6) /routes/users.js에는 get호출을 기다리는 라우터가 존재하고, get호출을 받아 아래 함수가 실행된다. 

이때, res.send를 통해 반환값 http response로 보내는데, json형태로 message라는 키에 메시지를 담아서 보낸다.

router.get('/', function(req, res, next) {
  console.log('user router')
  res.send({'message':'respond with a resource'});
});

7) 반환값을 곧바로 Api_test.js로 리턴되고, 리턴된 json데이터를 alert으로 화면에 보여준다.

const body = await response.json();
alert(body.message)

 

5. http통신(post방식)으로 node Api 호출

 

post 비동기 호출을 위해 C:\Users\ljung\OneDrive\문서\taling\client 경로에서

axios을 설치한다.

npm install --save axios

/src/components/폴더에 Api_test.js파일을 아래와 같이 수정한다.

import React, { Component } from 'react';
const axios = require('axios');

class App extends Component {
  state = {
    response: '',
  };
  
//페이지 로드시 실행 GET TEST
componentDidMount() {
  this.callApi()
    .then(res => this.setState({ response: res.express }))
    .catch(err => console.log(err));
}

callApi = async () => {
  try {
    const response = await fetch('/users');
    const body = await response.json();
    alert(body.message)
    if (response.status !== 200) throw Error(body.message);
    return body;
  } catch (error) {
    alert(error)
  }
};

// post 호출하기 버튼 클릭시 node api post 호출
submitClick = async e => {
  axios.post('/users', {
  })
  .then( response => {
      alert(response.data.message)
  })  

}

render() {
    return (
        <div>
          <button className="s_bt" type="submit" onClick={this.submitClick}>post 호출</button>
        </div>
    );
  }
}

export default App;

 

/routes/users.js 파일을 아래와 같이 수정한다.

post 호출을 위해 post router를 추가했다.

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  console.log('user router get')
  res.send({'message':'node get success'});
});

/* Post users listing. */
router.post('/', function(req, res, next) {
  console.log('user router post')
  res.send({'message':'node post success'});
});

module.exports = router;

post 호출 버튼을 누르면 아래와 같이 post api를 호출한 결과값이 alert 된다.

 

## 참고 ##

yarn을 사용하고 싶다면 아래 명령어로 설치한다. 설치가 되면, npm start 대신 yarn start로 서버실행 가능.

// window인경우
npm install -g yarn
// mac 에서 homebrew 사용할 경우
brew install yarn

https://heropy.blog/2017/11/25/yarn/

 

6. yarn과 concurrently을 설치한다.

npm install concurrently --save

concurrently 사용

  concurrently를 사용하면 여러개의 명령어를 하나의 콘솔에서 동시에 실행할 수 있다.

  --save 로 설치하면

  package.json > "dependencies":{} 안에 concurrently가 추가된다.

 

7. node 경로(C:\Users\ljung\OneDrive\문서\taling)에 있는 package.json파일을 아래와 같이 수정한다.

다른 부분을 다를 수 있고, "script": {} 이 부분을 수정한다.

 

코드설명 : concurrently를 사용하면 yarn server 라를 명령어와 yarn client라는 명령어를 동시에 실행 할 수있다.

yarn dev 명령어는 "concurrently --kill-others-on-fail \"yarn server\" \"yarn client\"" 를 실행시킨다.

yarn server nodemon server.js 라는 명령어를 실행해 node 서버를 키고,

yarn client cd client react 경로에 들어가 yarn start 명령어로 react 서버를 실행시킨다.

 

이렇게 하면 yarn dev라는 하나의 명령어로 react와 node 서버를 모두 켤 수 있다.

{
  "name": "project202001",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "client": "cd client && yarn start",
    "server": "nodemon server.js",
    "dev": "concurrently --kill-others-on-fail \"yarn server\" \"yarn client\""
  },
  "dependencies": {
    "concurrently": "^5.0.2",
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "jade": "~1.11.0",
    "morgan": "~1.9.1"
  }
}

8. server.js파일에 포트 5000으로 호출할 경우, node 서버를 실행한다는 코드를 추가한다.

  원래 코드는 아래와 같은데 

  "scripts": {
    "start": "node ./bin/www"
  },

  npm start 명령어를 실행하면 /bin/www 파일이 실행이 됐다. 아래 www 소스에 노드서버 포트를 5000으로 설정해 준다는 코드가 있다.

var port = normalizePort(process.env.PORT || '5000');
app.set('port', port);

그런데 바뀐 코드에서는 www 파일이 아닌 server.js 파일을 실행하니, server.js에 포트설정 코드를 추가해 줘야한다.

server.js파일을 아래와 같이 수정한다.

var express = require('express');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

app.use('/', indexRouter);
app.use('/users', usersRouter);

const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Listening on port ${port}`));

9. react node 서버를 동시 구동한다.

  C:\Users\ljung\OneDrive\문서\taling 경로에서 yarn dev 명령어를 실행하면, 아래와 같이 하나의 명령어로 react, node 서버를 동시에 구동할 수 있다.

 

https://taling.me/Talent/Detail/19341

 

[2월/주말] REACT, NODE, MYSQL, AWS 개발부터 배포까지/ 따라하면 완성되는 웹프로젝트. | 탈잉

# 수업의 최종목표 1. Font-end(react) <> back-end(node) <> mysql 구조를 프레임워크화 한다. 2. select, update, delete, insert를 각각 1세트씩 구현한다.(이 세트를 확장해서 하고 싶은 것을 자유롭게 만드시면 됩니다.) 3. AWS EC2 서버에 접근하여 파일을 컨트롤 할 수 있다. 4. AWS RDS(mysql) 인스턴스를 생성하고, 필요한 테이블들을 관리할 수 있다. CRUD 이외에 일반적인

taling.me

 

Comments