3-2. 프로젝트 구조잡기
이번 섹션에서는 프로젝트를 생성하고 기본적인 설정을 해보도록 하겠습니다.
이 섹션의 코드는 여기서 조회 할 수 있습니다.
프로젝트 생성 및 의존 모듈 설치
create-react-app 을 통하여 프로젝트를 생성하고, 앞으로 우리가 필요한 모듈들을 설치해주세요.
$ create-react-app memo-app
$ cd memo-app
$ yarn add axios immutable open-color react-click-outside react-icons react-immutable-proptypes redux react-redux redux-actions redux-pender react-textarea-autosize react-transition-group styled-components
$ yarn add cross-env --dev
뭔가, 의존 모듈이 꽤 많죠? 어떤 모듈들이 설치되었는지 하나하나 살펴보겠습니다.
- axios: 프로미스 기반 HTTP Client
- immutable: 임뮤터블 데이타 관리를 위한 도구
- open-color: 색상 라이브러리
- react-click-outside: 컴포넌트 바깥 클릭을 감지해주는 라이브러리
- react-icons: SVG 아이콘 세트
- react-immutable-proptypes: immutable 을 위한 proptypes
- redux, react-redux, redux-actions: 리덕스 관련
- redux-pender: 비동기 리덕스 액션 관리 라이브러리
- react-textarea-autosize: 자동으로 리사이징되는 textarea 컴포넌트
- react-transition-group: 애니메이션을 위한 리액트 라이브러리
styled-components: JS 내부에서 컴포넌트 스타일링을 도와주는 라이브러리
cross-env: 환경변수를 모든 운영체제에서 호환되는 형태로 설정해주는 라이브러리
프로젝트 루트 지정하기
우리가 프로젝트를 진행하다보면, '../modules/ui.js'
, 이런식으로 상대 경로를 통하여 파일을 불러오는데요. 디렉토리 구조가 복잡해지다보면 '../../modules/ui.js'
이런식으로 파일을 불러올때 불편한점이 생깁니다.
이런 점을 해결해주는 설정이 바로 프로젝트 루트 설정인데요, 프로젝트 루트 설정을 하고나면 다음과 같은 형식으로 파일을 불러올 수 있게 됩니다: 'modules/ui.js'
어떤가요? 꽤 편해보이죠?
이 설정은 웹팩을 통해 할 수 있는데요, 우리는 create-react-app 으로 프로젝트를 생성했기에 이 작업을 매우 간단하게 할 수있습니다.
프로젝트에서 package.json 을 열어서 start
스크립트를 다음과 같이 수정하세요:
"scripts": {
"start": "cross-env NODE_PATH=src react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
현재 GitHub 에 올라와있는 코드는
NODE_PATH
를 통해 루트 디렉토리 설정을 하지 않고npm run eject
를 하여 직접 디렉토리가 설정 되었습니다. 이 부분은 조만간 코드를 업데이트 하도록 하겠습니다.NODE_PATH
로 지정하는 편이 훨씬 깔끔하고 간편하니 이 방식으로 진행하세요.
jsconfig.json 파일 설정하기
프로젝트의 최상위 디렉토리에 jsconfig.json
파일을 생성하여 다음 내용을 입력하세요.
이 설정은 프로젝트 루트 설정을 하고 나서도 VSCode 에서 불러온 파일의 세부정보들을 제대로 불러와서 자동완성이 제대로 작동하도록 해줍니다.
jsconfig.json
{
"compilerOptions": {
"baseUrl": "./src"
}
}
프록시 설정
개발 서버에 프록시를 설정하겠습니다. 지금은 개발서버와 API 서버가 분리되어있지요? 이러한 상황에서는 webpack 에서 백엔드 프록시서버를 설정해주면 백엔드 서버의 API 를 개발서버에서도 자체적으로 사용 할 수 있게 됩니다.
보통은 웹팩에서 따로 설정을 해주어야하지만, create-react-app 으로 만든 프로젝트에서는 package.json
에서 간편하게 설정 할 수 있습니다.
package.json
파일의 하단에 "proxy": "http://localhost:3001"
을 추가해주세요.
(...)
"proxy": "http://localhost:3001"
}
파일 삭제
우리가 사용하게 되지 않을 (혹은 다시 만들) 파일들을 삭제하겠습니다. 다음 파일들을 삭제하세요:
- src/App.css
- src/App.js
- src/App.test.js
- src/logo.svg
디렉토리 생성
src 디렉토리 내부에 다음 디렉토리들을 생성하세요
- components: 프리젠테이셔널 컴포넌트들이 위치합니다
- containers: 컨테이너 컴포넌트들이 위치합니다
- lib: 스타일 관련 유틸코드 그리고 웹 API 가 정리된 파일이 위치합니다
- modules: 리덕스 관련 모듈들이 위치합니다.
App.js 생성 및 index.js 수정
비어있는 App 컴포넌트를 만들겠습니다.
src/containers/App.js
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div>
Hello MemoApp!
</div>
);
}
}
export default App;
그리고 이 컴포넌트를 index.js 에서 렌더링 하도록 설정하세요.
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from 'containers/App';
import './index.css';
ReactDOM.render(
<App />,
document.getElementById('root')
);
이제, 개발서버를 실행하여 Hello MemoApp! 이 제대로 뜨는지 확인해보세요.
$ yarn start
리덕스 모듈 생성하기
이제, 리덕스 모듈들을 만들겠습니다. 우리가 이번 프로젝트에서 사용할 리덕스 모듈은 ui 와 memo 입니다. ui 는 프로젝트의 전반적인 인터페이스 상태를 담당하고, memo 는 데이터 부분을 담당합니다.
지금은 내용이 비어있는 모듈을 만들건데요, 두 파일을 똑같은 내용으로 만들어주세요.
src/modules/memo.js
, src/modules/ui.js
import { handleActions } from 'redux-actions';
import { Map } from 'immutable';
const initialState = Map({
});
export default handleActions({
}, initialState);
이제, modules 의 index.js 파일에서, 리듀서를 합쳐주겠습니다.
이 과정에서, redux-pender 의 penderReducer 도 함께 합쳐주세요.
src/modules/index.js
import { combineReducers } from 'redux';
import { penderReducer } from 'redux-pender';
import memo from './memo';
import ui from './ui';
export default combineReducers({
memo,
ui,
pender: penderReducer
});
스토어 만들기
이제 리덕스 스토어를 만들어주겠습니다. src 디렉토리에 store.js 파일을 생성해서 다음 코드를 작성하세요.
src/store.js
import { createStore, applyMiddleware, compose } from 'redux';
import penderMiddleware from 'redux-pender';
import reducers from 'modules';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducers, composeEnhancers(
applyMiddleware(penderMiddleware())
));
export default store;
React DevTool 과 redux-pender 를 적용하여 스토어를 만들었습니다. 미들웨어와 개발도구를 함께 사용하기 위하여, compose 가 사용됩니다.
Provider 에 스토어 전달하기
이제 프로젝트에 리덕스를 적용하는 부분, Provider 를 설정해주겠습니다.
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from 'containers/App';
import { Provider } from 'react-redux';
import store from 'store';
import './index.css';
ReactDOM.render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root')
);
자, 프로젝트 초기설정을 마쳤습니다. 페이지를 열어서 Hello MemoApp! 이 잘 뜨는지 확인하고, Redux 개발자도구도 제대로 나타나는지 확인하세요.
이제 준비가 끝났으니, 본격적으로 개발을 시작해볼까요?