본문 바로가기
Today I learned

[react] 2 주차 - webpack으로 모듈화 그리고 create React App(2)

by soheemon 2020. 1. 18.

babel

babel은 브라우저가 지원하지 않는 자바스크립트 문법들을 브라우저가 이해 할 수 있도록 코드를 변환해주는 역할을 한다.

 

babel 예제

babel 설정 전에 arrowFunction을 사용해서 IE에서 돌려보자

크롬은 동작하지만, IE에서는 지원하지 않으므로 에러가 발생한다.
webpack.config.js에 추가한다.

webpack.config.js를 수정했으므로 다시 시작한다.

babel도 package.json의 browserlist를 참고하기 때문에, browserlist에 지정되지 않으면 적용이 되지 않을 수 있다.

그리고 browserlist는 package.json에서 공통적으로 관리하는것이 좋다.

 

babel load은 transcompiling 해준다. 브라우저가 이해 할 수 있는 js언어로 변경해준다.

 

eslint

lint: js의 코드스타일 규칙

eslinst는 자바스크립트 코드 스타일을 정하는 모듈. 프로젝트 공동개발자의 자바스크립트 코드를 비슷하게 맞추어 주는 역할을 한다.

+ ES6이상을 지원하기 위해서는 babel-eslint도 설치해야 한다.

사용자가 직접 규칙을 추가 할 수도 있지만, 이미 만들어진것을 상속받아서 쓸 수도 있다.

npm i -D eslint-config-standard
#lint error가 나면 commit하면 안됩니다.
react는 react-app이라는 eslint config를 사용 하고 있다.

 

commonjs 모듈화

모듈화 하는방법

  1. 전체를 모듈화 module.exports
  2. 개별로 모듈화 exports.변수명

모듈 가져오는 방법

require

//개별로 모듈화
exports.area = function(r) {
  return Math.PI * r * r;
};
 
exports.circumference = function (r) {
  return 2 * Math.PI * r;
};

//전체 모듈화
module.exports = {
  bulk: function (x) {
    return x * x * x;
  }
};

//모듈 불러와서 사용하기
var circle = require('./circle');
var cube = require('./cube');
 
console.log(circle.area(10));
console.log(circle.circumference(10));
 
console.log(cube.bulk(10));

ES6 모듈화

개별 모듈화 named export

전체 모듈화 default export

가져오기

import

 

named export & import

예제

개별 js에서 export 한다.
entry Point js에서 import해서 실행한 모습

주의할점은 import {area} from '{js파일 경로}' 에서 {area} 는 반드시 동일한 이름으로 import 해줘야 한다.

 

Default export & import

 

Default import

git

git은 원격 저장소에 저장 전에 staging 영역에 관리할 파일을 추가해야 한다.

staging영역에 추가되어야 tracking해야할 대상이라는것을 알고 변경사항들을 추적하게 된다.

 

git은 변경사항을 snapshot으로 저장한다.

SVN처럼 commit된것을 저장하는것이 아니라 commit과 commit사이에 변경된 snapshot으로 저장한다. 따라서 브랜치를 많이 만들어도 부담이 없다.

 

소스가 아닌것은 .gitignore에 명시

형상관리시스템에는 소스만 저장해야 한다. 3rd party 라이브러리 같이 남이 만든 라이브러리나, 개발툴 환경파일, 컴파일 된 결과물은 형상관리 대상이 아니다..!

다른 개발자가 clone받아서 개발 할 수 있는 코드만 넣어두어야 한다.

 

따라서 이런 파일들은 .gitignore에 넣어두어야 한다.

 

gitignore에 dependency package 및 설정파일 들을 작성한 모습

 

다른 칭구칭긔들과 저장소를 공유하고 싶다면 원격저장소를 사용해요.

github

gitlab

 

git은 같은 파일이 아니더라도 다른사람이 먼저 push한다면 에러가 난다. (SVN은 같은 파일만 아니면 가능)

그래서 항상 pull받는 습관을 들어야 한다.

 

다시 Create-React-App 으로 돌아가자

 

version은 production과 development 으로 나누어서 관리 가능하다.

 

 

 

 

 

 

 

 

 

 

entry Point가 되는 index.js

여기서 import는 {}가 없으므로 default import에 해당한다.

 

 

App.js에 지난주에 만들었던 scoreBoard 코드를 가져오자.

index.js는 아래와 같이 지난주에 만들었던 App을 가져온다.

 

Scr폴더에 components폴더를 만들고, Header.js파일을 만들어서, App.js에서 하나로 합쳐져있는 component들을 각각 파일별로 분리해보자

 

1. Header.js를 생성 후 componenet를 named export한다.

 

2. App.js에서 import한다.

3. 나머지 Component들도 export & import 하자.

 

모듈화 최종..!

Component Communication

1. Unidirectional Data Flow

2개 이상의 컴포넌트에서 공유해야 할 state가 있다면 application state로 정의하고 props로 데이터를 전달 받는게 관리하기 편하다.

데이터는 최상위 컴포넌트에서 하위방향으로 흐른다. 이것을 Unidirectional DataFlow라고 한다.

Application state에서 값을 변경하면 변경된 값이 아래 컴포넌트 트리의 아래 방향으로 전달된다.

 

2. Lifting state Up

local State는 다른 component들과 공유 할 수 없다. 데이터를 최상위component가 가지고 있어야 한다.

local state를 다른 컴포넌트와 공유하기 위해 부모컴포넌트에 state를 관리하는것을 lifting up이라고 한다.

 

"결국, 부모컴포넌트에서 state를 관리하고, 해당 컴포넌트에서 상태를 변경해주는 function도 같이 내려준다.

그러면 자식컴포넌트에서 이벤트가 발생할때 해당 function을 호출하면 된다."

 

예 - Counter componenet가 관리하던 state를, 부모컴포넌트인 App으로 올린다.

 

 

이제는 부모에게 증가시켜달라고 요청 해야한다.

1) 부모에서 점수를 증/감하는 function을 만들고

2) 자식에서는 해당 function을 호출한다.

 

//App.js

class App extends React.Component {
  state = {
    players: [
      {name: 'LDK', score: 0, id: 1},
      {name: 'HONG', score: 0, id: 2},
      {name: 'KIM', score: 0, id: 3},
      {name: 'PARK', score: 0, id: 4},
    ]
  };
  
  /*Counter에 내려 줄 메서드*/
  handleChangeScore = (index, delta) => {
    console.log('index: ' + index, 'delta: ' + delta);
  }
  
  render() {
    return (
      <div className="scoreboard">
        <Header title="My scoreboard" totalPlayers={this.state.players.length} />
        
        {/*Players List*/}
        { this.state.players.map(item => <Player name={item.name} score={item.score}
                                                 key={item.id.toString()} removePlayer={this.handleRemovePlayer}
                                                 id={item.id} />)
        }
      </div>
    );
  }
}

//Player.js

<counter score="{props.score}"></counter>

//Counter.js

class Counter extends React.Component {
  render() {
    return (
      <div className="counter">
        <button className="counter-action decrement"> - </button>
        <span className="counter-score">{this.props.score}</span>
        <button className="counter-action increment"> + </button>
      </div>
    );
  }
}

// Counter component는 더이상 stateful 하지 않으므로, 
// classComponenet가 아닌, function Componenet로 바꾸는게 효율적이다.

const Counter = (props) => {
  return (
    <div className="counter">
      <button className="counter-action decrement"> - </button>
      <span className="counter-score">{props.score}</span>
      <button className="counter-action increment"> + </button>
    </div>
  )
}

App.js 에서 함수를 만들어 준다.

 

 

 

호출하는 부분.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

곁다리

함수 타고 들어가기: ctrl + b

이전으로 돌아가기 ctrl + alt + <-

웹스톰은 하나의 창에 하나의 프로젝트를 열 수 있다.

clone 받을때 새로운 폴더를 만들어서 받기..!
프로젝트 받았는데, Dependency가 없을때..! 에러로 알려준다.

 

댓글