2. express 적용하기

React 2017. 7. 10. 11:14

필요 패키지 설치하기


express 모듈 설치

npm install --save express


개발 모드에서 사용할 babel 관련 모듈들과 nodemon 설치.

nodemon은 코드에 변화가 감지되면 서버를 재시작해주는 모듈입니다.

npm install -save-dev babel-cli babel-core babel-preset-es2015 nodemon


폴더 & 파일 생성하기

src폴더 하위 디렉토리로 server 폴더를 생성하고, index.js 파일을 생성해주세요.

그리고 server폴더 하위에 routes폴더를 생성하고, index.js파일을 생성해주세요.

추가적으로 server 폴더 하위에 scripts폴더도 생성하고, nodemon.js 파일을 생성해주세요.




메인 파일 작성 - src/server/index.js


import express from 'express';

const app = express();
const port = 3100;

app.use('/', express.static(__dirname + '/../../build'));

app.listen(port, () => {
console.log('Server is listening on port', port);
});



라우트 파일 작성 - src/server/routes/index.js


import express from 'express';

const router = express.Router();

const testData = {
name: 'jaro',
project: 'react'
}

router.get('/', (req,res) => {
res.json(testData);
});

export default router;

   

개발용 서버 실행 스크립트 작성 - src/server/scripts/nodemon.js


process.env.NODE_ENV = 'development';

var nodemon = require('nodemon');
nodemon('--exec babel-node --presets=es2015 ./src/server/index.js --watch ./src');

nodemon.on('start', function() {
console.log('[nodemon] App has started');
}).on('quit', function() {
console.log('[nodemon] App has quit');
process.exit();
}).on('restart', function(files) {
console.log('[nodemon] App restarted due to:', files);
});


development 스크립트를 굳이 스크립트파일을 따로 만든 이유는, 윈도우 / 유닉스 계열에서 NODE_ENV 설정하는 방식이 다르기 때문입니다.

 "development": "NODE_ENV=development nodemon --exec babel-node --presets=es2015 ./server/main.js --watch server",
 "win_development": "set NODE_ENV=development&nodemon --exec babel-node --presets=es2015 ./server/main.js --watch server"

스크립트 파일을 따로 만들기 싫으면 위와같이 package.json 에 스크립트를 작성해도 됩니다.

- 출처 : https://velopert.com/2037


자 그럼 우선 서버를 실행하여 제대로 작동하는지 알아보겠습니다.

package.json을 열어서 script를 추가해주세요

"start:server": "node ./src/server/scripts/nodemon.js",

후에 터미널에서 npm run start:server 를 입력하면, express 서버가 실행됩니다.

localhost:3100/api 로 접속하여 testData가 브라우져에 출력되는지 확인해주세요

정상 출력이 되는것을 확인했다면, 이제 ajax를 이용하여 통신을 하도록 해보겠습니다.


저는 axios라는 모듈을 사용하겠습니다.

물론 jquery 나 fatch 등과 같은 여러 모듈을 사용 가능합니다. 본인이 사용하기 편한 모듈을 선택하시기 바랍니다.


axios 설치

npm install -S axios

이제 테스트를 하기 위해 src/app.js 파일에 추가하겠습니다.


import React, { Component } from 'react';
import './App.css';
import axios from 'axios';

class App extends Component {

constructor(props) {
super(props);
this.state = {
name: '',
project: ''
}
this._onClick = this._onClick.bind(this);
}

_onClick() {
axios.get(`/api`)
.then( response => {
this.setState({
name: response.data.name,
project: response.data.project
});
}) // SUCCESS
.catch( response => { console.log(response); } );
}

render() {
const { name , project } = this.state;
return (
<div className="App">
<h1>{project}</h1>
<h1>Hello {name}</h1>
<button onClick={this._onClick}>api 호출</button>
</div>
);
}
}

export default App;


import axios from 'axios';

axios 모듈을 사용하겠다는 뜻입니다.


constructor(props) {
super(props);
this.state = {
name: '',
project: ''
}
this._onClick = this._onClick.bind(this);
}

app 컴포넌트 클래스가 생성되면서 불리는 생성자 함수입니다.

_onClick() {
axios.get(`localhost:3100/api`)
.then( response => {
this.setState({
name: response.data.name,
project: response.data.project
});
}) // SUCCESS
.catch( response => { console.log(response); } );
}

버튼을 눌렀을때 실행되는 함수입니다. 


<h1>{project}</h1>
<h1>Hello {name}</h1>

브라우져에 this.state 의 name과 project를 표시합니다.

기본값은 '' 이므로 처음에는 아무것도 표시되지 않다가, 버튼을 누르면 데이터를 받아 표시하게 됩니다.


<button onClick={this._onClick}>api 호출</button>

버튼을 추가하고, 버튼을 눌렀을때 실행되는 함수를 바인딩 해주었습니다.


이제 리액트 서버와 express 서버를 둘다 실행하여 확인해보겠습니다.

터미널 2개를 열어

한곳에서는 npm start

한곳에서는 npm run start:server

이렇게 2개를 실행시켜 주세요



버튼이 생성되어있고, 버튼을 눌러도 아무런 반응이 없습니다. 

콘솔창을 확인해보겠습니다.

에러가 떠있습니다.

받아올수 없다네요 크로스 도메인 문제라고 알고있습니다. ( 자세히 공부해서 포스팅 하겠습니다. )

이 경우에는 proxy를 통해 간단히 이 문제를 해결 가능합니다.

javascript에서 동일 서버의 URL을 호출하고, 
이 URL에서 내부적으로 다른 도메인의 URL을 호출하는 것으로, 

package.json에 proxy를 추가하여 해결하겠습니다.


"proxy": "http://localhost:3100/"

를 추가해주세요.

그리고 onClick 함수를 변경합니다.


_onClick() {
axios.get(`/api`)
.then( response => {
this.setState({
name: response.data.name,
project: response.data.project
});
}) // SUCCESS
.catch( response => { console.log(response); } );
}


자체에서 url을 호출한뒤 다시 proxy의 url을 호출하므로 기존에 get 주소중 localhost:3100을 지우면 됩니다.

그리고 서버들을 다 종료 후 다시 켜주세요.

그래야 제대로 작동합니다.

다시 서버가 실행되고 버튼을 누르면, 제대로 작동할것입니다.





이번 포스팅은 간단한 exress 적용과, ajax를 이용하여  웹서버와의 통신하는것을 간략하게 포스팅 하였습니다.

이번 포스팅에 사용된 소스는 https://github.com/JaroInside/tistory-react-express 에서 보실수 있습니다.

감사합니다.




추가적으로, 두개의 터미널을 띄워서 실행하는것이 불편하신분들은


npm-run-all 이라는 패키지를 설치하시기 바랍니다.

이 패키지는 npm의 여러 스크립트를 동시에 실행시켜줄수 있는 패키지로, 이번 포스팅처럼 리액트 서버와 웹서버를 동시에 실행하여야 할때 매우 간편합니다.


깃헙 주소

https://github.com/mysticatea/npm-run-all


설치

npm install -D npm-run-all


사용법

package.json의 script를 수정하겠습니다.


"start": "npm-run-all --parallel start:**",
"start:client": "react-scripts start",
"start:server": "node ./src/server/scripts/nodemon.js",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"


start 를 npm 스크립트들중 start: 로 시작하는것들을 모두 한번에 실행한다는 명령어로 바꾸었습니다.

기본의 start 명령어, 즉 react 개발서버 명령어는 start:client로 변경하였고,

웹서버 명령어는 start:server 명령어로 만들어 하나의 터미널에서 npm start 명령어 하나로 모든 명령어를 동시에 실행할수 있게 하였습니다.


'React' 카테고리의 다른 글

react-image-cropper 사용하기  (0) 2017.07.22
1. CRA로 프로젝트 생성  (1) 2017.07.10
블로그 이미지

Jaro

대한민국 , 인천 , 남자 , 기혼 , 개발자 jaro0116@gmail.com , https://github.com/JaroInside https://www.linkedin.com/in/seong-eon-park-16a97b113/

,

시작하기



만일 nodejs가 설치되어 있지 않다면, 우선 nodejs를 설치해주세요.

https://nodejs.org/ 에서 설치 파일을 다운받으셔도 되고,

버젼관리를 쉽게 하고자 한다면, nvm ( node version manager ) 를 추천드립니다.

https://github.com/creationix/nvm

위 링크에서 nvm을 다운받거나 install script를 이용하여 설치하신다음,

터미널을 재시작 해주시면 사용이 가능합니다.

기본적인 명령어로는

1. nvm install node

- nodejs 가장 최신 버젼이 설치됩니다.(current version) 만일 최신버젼이 아닌 다른 버젼을 설치하고 싶다면, 예를 들어 7.6.0 버전을 설치하고 싶다면,

   nvm install 7.6.0 명령어를 사용하시면 됩니다.

2. nvm use node

- 현재 설치되어있는 가장 최신 버젼의 nodejs를 사용합니다. 만일 설치되어있는 다른 버젼을 사용하시려면, 예를 들어 7.6.0 버전을 사용하고 싶다면,

   nvm use 7.6.0 명령어를 사용하시면 됩니다.

   이렇게 사용하는 이유는 각 node 버젼마다 글로벌 패키지랄 다르게 적용할수 있고, 프로젝트에 따라서 사용해야하는 node 버전이 다를수 있기 때문입니다.

3. nvm uninstall x.x.x

- 설치되어 있는 x.x.x버전의 nodejs를 삭제합니다.




자신의 컴퓨터에 create-react-app을 글로벌 패키지로 설치해줍니다.

npm install -g create-react-app


프로젝트 생성

create-react-app projectname


위 명령어를 실행하면, projectName의 이름을 가진 폴더가 생성되면서,  react 프로젝트가 생성되며, 

그 다음 자동으로 각종 package들을 설치하게 됩니다. 약3~5분정도의 시간이 걸리는듯 싶습니다.

( 프로젝트 명은 모두 소문자로 하셔야 합니다. 대문자로 하면 

이러한 에러메시지가 나와요.


생성을 기다립니다.


이러한 명령어가 뜨면서 프로젝트 생성이 완료되었습니다.

저는 yarn을 설치해서 yarn으로 프로젝트 생성이 되었습니다. yarn 은 필수가 아니므로 사용하셔도, 안하셔도 됩니다.


자 그럼 우선 생성된 프로젝트를 살펴보겠습니다.

폴더 구조입니다. ( 참고로 사용하는 editer 는 vscode 입니다 )

구성이나 복잡한 폴더 구조가 없으며 앱을 빌드하는데 필요한 파일 만 있습니다. 

여기서 public/index.html은 템플릿 파일입니다. 필수적인 파일이므로 파일의 위치와 이름을 바꾸지 않으시길 바랍니다.

src/index.js 파일 또한 javascript의 진입 파일이므로 이름과 위치는 바꾸지 않으시길 바랍니다.

( 추후에 설명드릴 npm eject 명령어로 설정파일을 커스텀마이징 할 경우, 바꾸는게 가능하긴 합니다. 허나 저는 eject를 하지 않고 이번 포스팅을 할 예정입니다. )


스크립트

생성이 완료되었고, 폴더 구조도 보았습니다.

이제 사용 가능한 스크립트들을 살펴보겠습니다.

우선 package.json의 내용을 확인하겠습니다.


{
"name": "projectname",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-scripts": "1.0.10"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}


역시 깔끔합니다. 물론 여기에는 dependencies가 3개밖에 없지만, 사실은 매우 많은 dependencies 가 있습니다. 숨겨진채로...

여기서 볼것은 scripts입니다.

총 4개의 스크립트 명령어가 있습니다.

1. start

- npm run start ( 혹은 npm start ) 로 실행합니다. react 개발 서버를 실행하는것으로, 개발모드에서 앱을 실행합니다. 브라우져에서 localhost:3000 에서 확인 가능합니다.

  코드 수정시 페이지는 다시 로드 되며, lint 오류는 콘솔에 표시됩니다.

  

  생성후 바로 npm start 를 실행한 뒤 화면입니다.


2. build

- npm run build 로 실행합니다. 프로덕션용 앱을 build 하는 과정이며, React를 프로덕션 모드로 올바르게 번들링하고 최상의 성능을 위해 빌드를 최적화합니다.

  빌드가 축소되고 파일 이름에 해시가 포함됩니다.

  

  명령어를 실행해보겠습니다.


생성된 build 폴더 구조입니다.


3. test

- npm run test 로 실행합니다. 테스트 러너를 시작하는 명령어로, Jest를 테스트 러너로 사용합니다.

  


4. eject

- npm run eject 로 실행합니다. 현재 프로젝트의 모든 설정 및 스크립트를 개발자가 사용할수 있도록 밖으로 끄집어냅니다. 

  프로젝트의 단일 빌드 종속성을 제거합니다. 이 명령어를 사용한뒤에는 각종 설정파일들(Webpack, Babel, ESLint 등)을 커스텀마이징 할수 있게 됩니다.

  하지만, 이 명령어는 단방향 명령입니다!! 한번 실행하면 이전으로 돌아갈수 없습니다!! 

  


이번 포스트에서는 CRA로 프로젝트 생성과 폴더 구조, 스크립트 실행에 대해 포스팅 하였습니다.

다음 포스트에서는 express 작업환경 설정에 대해 포스팅 하도록 하겠습니다.



참고 사이트 : https://github.com/facebookincubator/create-react-app

'React' 카테고리의 다른 글

react-image-cropper 사용하기  (0) 2017.07.22
2. express 적용하기  (0) 2017.07.10
블로그 이미지

Jaro

대한민국 , 인천 , 남자 , 기혼 , 개발자 jaro0116@gmail.com , https://github.com/JaroInside https://www.linkedin.com/in/seong-eon-park-16a97b113/

,


2017.07 React with TypeScript 스터디 정리.


tsconfig


tsconfig.json 파일은 TypeScript를 위한 단위 환경 설정 파일입니다.

TypeScript 컴파일러 수행시에 참조되며, 각종 옵션들을 설정할수 있습니다.

기본적으로 생성되는 파일의 내용입니다.


{
"compilerOptions": {
"outDir": "build/dist", // 빌드 결과물 폴더 입니다.
"module": "commonjs", // 빌드 결과의 모듈 방식은 commonjs 방식으로 한다는 뜻입니다.
"target": "es5", // 빌드 결과물은 es5 방식으로 한다는 뜻입니다.
"lib": ["es6", "dom"], // 라이브러리는 es6 와 dom 으로 한다는 뜻입니다.
"sourceMap": true, // .map.js 파일도 함께 생성한다는 뜻입니다.
"allowJs": true, // JS 파일도 컴파일 대상이라는 뜻입니다.
"jsx": "react", // jsx 구문 사용 가능입니다.
"moduleResolution": "node", // 모듈 해석 방식은 node 처럼 한다는 뜻입니다.
"rootDir": "src", // 컴파일할 대상들이 들어있는 폴더 (루트 폴더) -> 즉 이 폴더 안에서 작업 하셔야 합니다.
"forceConsistentCasingInFileNames": true, // https://github.com/TypeStrong/ts-loader/issues/89 -> 이슈체크!
"noImplicitReturns": true, // 제대로 리턴 다 안되면 에러 -> 오류에 대해 강력하게 체크한다는 뜻입니다.
"noImplicitThis": true, // this 표현식에 암시적으로 any 로 추론되면 에러를 알려줍니다. -> any를 사용하는건 매우 비추천합니다.(typescript...)
"noImplicitAny": true, // 암시적으로 선언되었는데 any 로 추론되면 에러를 알려줍니다.
"strictNullChecks": true, // null 이나 undefined 을 서브 타입으로 사용하지 못하게 합니다.
"suppressImplicitAnyIndexErrors": true, // 인덱싱 시그니처가 없는 경우, 인덱스를 사용했을때 noImplicitAny 에 의해 에러가 뜨는 것을 방지합니다
"noUnusedLocals": true // 사용 안하는 로컬 변수가 있으면 에러를 알려줍니다.
},
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
],
"types": [
"typePatches"
]
}


tsconfig에 대한 자세한 설명은

https://basarat.gitbooks.io/typescript/content/docs/project/tsconfig.html 를 참조하여 보시기 바랍니다.


tslint


TSLint는 TypeScript 코드에서 가독성, 유지 관리 가능성 및 기능 오류 를 검사하는 확장 가능 정적 분석 도구입니다 . 

최신 편집자 및 빌드 시스템에서 광범위하게 지원되며 사용자 자신의 린트 규칙, 구성 및 포맷터로 사용자 정의 할 수 있습니다.

{
"extends": ["tslint-react"],
"rules": {
"align": [
true,
"parameters",
"arguments",
"statements"
],
"ban": false,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"eofline": false,
"forin": true,
"indent": [ true, "spaces" ],
"interface-name": [true, "never-prefix"],
"jsdoc-format": true,
"jsx-no-lambda": false,
"jsx-no-multiline-js": false,
"label-position": true,
"max-line-length": [ true, 120 ],
"member-ordering": [
true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-any": true,
"no-arg": true,
"no-bitwise": true,
"no-console": [
true,
"log",
"error",
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-consecutive-blank-lines": true,
"no-construct": true,
"no-debugger": true,
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
"no-shadowed-variable": true,
"no-string-literal": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": false,
"no-unused-expression": true,
"no-use-before-declare": true,
"one-line": [
true,
"check-catch",
"check-else",
"check-open-brace",
"check-whitespace"
],
"quotemark": [true, "single", "jsx-double"],
"radix": true,
"semicolon": [true, "always"],
"switch-default": true,

"trailing-comma": false,

"triple-equals": [ true, "allow-null-check" ],
"typedef": [
true,
"parameter",
"property-declaration"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore", "allow-pascal-case"],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-module",
"check-operator",
"check-separator",
"check-type",
"check-typecast"
]
}
}


아래 링크에서 각 기능들을 보시는걸 추천합니다.

https://github.com/palantir/tslint


이번 포스팅은 사실 큰 내용이 없이 거의 링크로 대체하였습니다.

(사실 저도 공부하는 수준이라 자세히 모릅니다.)

하지만 제가 어줍잖은 지식으로 설명하는것보다는 공식 페이지를 참고하시는게 더 좋을듯 싶어서 링크로 대체하였습니다.



참고 슬라이드 - http://slides.com/woongjae/react-with-typescript-1#/

참고 동영상 - https://www.youtube.com/playlist?list=PLV6pYUAZ-ZoHx0OjUduzaFSZ4_cUqXLm0

'React > React&typeScript' 카테고리의 다른 글

6. stateless Component  (0) 2017.07.12
5. Component  (0) 2017.07.10
3. CRA  (0) 2017.07.07
2. TypeScript  (0) 2017.07.07
1. React  (0) 2017.07.07
블로그 이미지

Jaro

대한민국 , 인천 , 남자 , 기혼 , 개발자 jaro0116@gmail.com , https://github.com/JaroInside https://www.linkedin.com/in/seong-eon-park-16a97b113/

,