Create-react-app V2 릴리즈! 무슨 변경 사항이 있을까?

Minjun Kim·2018년 10월 2일
44
post-thumbnail

리액트 개발자라면 애용하고 계실 도구인 create-react-app 의 v2 버전이 릴리즈되었습니다! 기존에 만든 자료들을 업데이트해야 한다는 점 (특히 책... 따흑... )은 조금 귀찮긴 하지만, 좋아하는 도구가 더 멋져졌으니까, 정말 듣기좋은 소식인데요!

이 포스트에서는 v2 에서 어떠한 변화가 적용되었는지 한번 살펴보도록 하겠습니다.

업데이트의 자세한 내용은 다음 링크에서 확인 할 수 있습니다.

설치 및 사용

사용방법은 딱히 바뀌지 않았습니다.

$ npx create-react-app what-is-new
$ cd what-is-new
$ yarn start

1. Sass, CSS Module 지원

Sass 와 CSS Module 을 yarn eject 하지 않고 사용 할 수 있습니다. 저처럼 Sass를 자주 쓰시는 편이라면 정말 반가운 소식이겠네요!

Sass

Sass 를 사용하기 위해선, 사전에 node-sass 를 설치하시면 됩니다.

$ yarn add node-sass

정말 되는지 한번 써볼까요?

src/MyComponent.js

import React from 'react';
import './MyComponent.scss';

const MyComponent = () => {
  return (
    <div className="MyComponent">
      <div className="something-inside">Hello CRA v2</div>
    </div>
  );
};

export default MyComponent;

src/MyComponent.scss

.MyComponent {
  background: black;
  color: white;
  padding: 1rem;
  .something-inside {
    background: white;
    color: black;
    font-size: 2rem;
    text-align: center;
    padding: 1rem;
  }
}

src/App.js

import React, { Component } from "react";
import MyComponent from "./MyComponent";

class App extends Component {
  render() {
    return (
      <div>
        <MyComponent />
      </div>
    );
  }
}

export default App;

image.png

오호, 그냥 하니까 되는군요! 👍

CSS Module

CSS Module 은 사용 방식이 이전과 조금 다릅니다. 파일을 생성하실 때 파일이름.module.css 이런식으로 하시면 CSS Module 이 적용됩니다.

한번 해볼까요?

src/AnotherComponent.module.css

.wrapper {
  background: gray;
  color: white;
  padding: 1rem;
  font-size: 2rem;
}

src/AnotherComponent.js

import React from 'react';
import styles from './AnotherComponent.module.css';

const AnotherComponent = () => {
  return <div className={styles.wrapper}>What about CSS Module?</div>;
};

export default AnotherComponent;

src/App.js

import React, { Component } from 'react';
import MyComponent from './MyComponent';
import AnotherComponent from './AnotherComponent';

class App extends Component {
  render() {
    return (
      <div>
        <MyComponent />
        <AnotherComponent />
      </div>
    );
  }
}

export default App;

image.png

2. Babel 7 업그레이드

Babel7 로 업그레이드 되면서 빌드속도가 개선된다고 합니다. 추가적으로, preset-typescript 를 통한타입스크립트 지원자동 Polyfill 등의 기능이 도입되었습니다.

리액트 개발자들이 주목해야 될 부분은 JSX Fragment <>...</> 문법을 이제 별도의 설정 커스터마이징 없이도 사용 할 수 있다는 점 입니다.

한번 써볼까요?

src/App.js

import React, { Component } from 'react';
import MyComponent from './MyComponent';
import AnotherComponent from './AnotherComponent';

class App extends Component {
  render() {
    return (
      <>
        <MyComponent />
        <AnotherComponent />
      </>
    );
  }
}

export default App;

3. Webpack v4 업그레이드

웹팩 v4 로 업그레이드되었다고 합니다. 이로 인하여 번들링 성능도 개선될거고, 본문에 의하면 JS 번들을 더 똑똑하게 분리시킨다고 합니다. yarn build 를 입력해보니

image.png

1.chunk.js 에는 자동으로 react, react-dom 관련 코드 들이 들어있고 main.js 쪽에 우리가 만는 컴포넌트들의 코드가 들어있습니다.

옛날에 CommonsChunkPlugin 를 사용해서 해야했던 작업들이 optimization.splitChunks 라는 API 를 통하여 자동으로 이뤄진다고 하네요.

추가적으로, 비동기 코드 스플리팅을 위하여, 옛날 문법인 require.ensure 를 기존에 사용하시는 분이 계시다면 이제 그 문법은 더 이상 사용하지 못하니 import() 로 바꾸셔야겠습니다!

4. SVG 를 리액트 컴포넌트화 하여 불러오기

SVG 파일을 불러올 떄 이전처럼 그냥 불러올 수 도 있지만:

import logo from './logo.svg';

이제 컴포넌트 형태로 변환하여 불러올 수 있다고 합니다.

import { ReactComponent as Logo } from './logo.svg';

위와 같이 ReactComponent 를 불러올 수 있네요!

한번 해볼까요?

import React, { Component } from 'react';
import MyComponent from './MyComponent';
import AnotherComponent from './AnotherComponent';
import { ReactComponent as Logo } from './logo.svg';

class App extends Component {
  render() {
    return (
      <>
        <MyComponent />
        <AnotherComponent />
        <Logo />
      </>
    );
  }
}

export default App;

디자이너한테 SVG 를 전달 받았을 때 보통 직접 컴포넌트화 하거나, img 태그로 불러왔었는데, 별도의 설정 없이 이렇게 불러올 수 있으니 편리하네요!

5. proxy 설정을 커스터마이징 가능

웹팩 갸벌 서버에서 백엔드 API 를 호출 할 때 발생 할 수 있는 CORS 관련 오류를 방지하기 위하여 웹팩 개발 서버에 proxy 를 설정 할 수 있는데요, 이는 이전부터 package.json 에서 proxy 필드를 설정해주면 됐었습니다. 지금도 똑같이 하시면 되는데요:

{
  "name": "what-is-new",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "node-sass": "^4.9.3",
    "react": "^16.5.2",
    "react-dom": "^16.5.2",
    "react-scripts": "2.0.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "proxy": "https://jsonplaceholder.typicode.com"
}

이제 이 설정을 커스터마이징 할 수 있게 되었습니다. 만약에 그 중간 단계에서 추가작업을 하고 싶다면, 이 proxy 는 지우고, http-proxy-middleware 라는 모듈을 설치 후 src 디렉토리에 setupProxy.js 라는 파일을 생성하세요.

$ yarn add http-proxy-middleware axios

src/setupProxy.js

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    proxy('/posts', {
      target: 'http://jsonplaceholder.typicode.com/',
      changeOrigin: true
    })
  );
};

여기서 사용하는 app 은 Express 서버 인스턴스입니다. 그리고 proxy 쪽에 changeOrigin 의 경우엔 jsonplaceholder 에서 Origin 을 전달하지 않으면 제대로 요청이 처리가 되지 않기 때문에 넣어주었습니다. 만약에 여러분의 API 서버에서 Virtual Host (요청 받는 Domain 이름에 따라 다른 요청 처리하기) 를 사용하고 있다면 이 설정을 해주셔야 합니다.

이제 App.js 에서 axios 를 사용하여 웹 요청을 해볼까요?

$ yarn add axios

src/App.js

import React, { Component } from 'react';
import axios from 'axios';

class App extends Component {
  state = {
    data: null
  };
  getPost = async () => {
    try {
      const response = await axios.get('/posts/1');
      this.setState({
        data: response.data
      });
    } catch (e) {
      console.log(e);
    }
  };
  componentDidMount() {
    this.getPost();
  }
  render() {
    if (!this.state.data) {
      return <div>로딩중...</div>;
    }
    const { title, body } = this.state.data;

    return (
      <div>
        <h1>{title}</h1>
        <p>{body}</p>
      </div>
    );
  }
}

export default App;

image.png

6. Good bye, IE

CRA v2 부터는 Internet Explorer 를 기본적으로 아예 지원하지 않는다고합니다. 지원이 필요하다면 react-app-polyfill 을 사용하셔야합니다.

$ yarn add react-app-polyfill

그리고 src/index.js 에서 이 스크립트를 추가하세요.

import 'react-app-polyfill/ie9'; // For IE 9-11 support
import 'react-app-polyfill/ie11'; // For IE 11 support

이 polyfill 에 대한 자세한 내용은 여기에서 확인 하실 수 있습니다.

기타

이 외에도 물론 다른 변경사항들이 있지만 딱히 크게 와닿지는 않는 변경사항이라 상세설명은 생략했습니다. 더욱 자세히 알고 싶다면 CRA v2 공식 블로그 포스트 를 참고하세요.

Yarn Plug n Play

CRA v2 리뷰하면서 처음 본건데.. node_modules 를 더 이상 사용하지 않는 yarn 의 기능인가봅니다. 이걸 실험적으로 지원한다고 하네요. 아직 어떤 이점이 있는지 모르겠지만 만약 유의미하다고 느껴지면 나중에 벨로그에 포스트 작성해보겠습니다.

최신 Node target 으로 작성된 라이브러리 사용가능

ES5 형태로 번들링되지 않는 라이브러리, 예를들어 query-string 최신 버전은 ES6 로 작성되어 npm 에 등록되어 있는 상태인데, 이전 CRA 에선 이걸 사용하면 빌드할때 오류가 났었는데요, 이제는 오류 나지 않고 사용 가능하다고 하네요.

Service worker 를 직접 켜야함

기존에는 Service worker 가 기본적으로 적용되어있었는데 이제는 직접 켜줘야만 작동합니다. index.js 를 보시면

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, 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: http://bit.ly/CRA-PWA
serviceWorker.unregister();

저기에 최하단에 있는 unregister -> register 로 변경하시면 됩니다.

그리고 이제는 이 서비스워커가 구글의 Workbox 기반이라고 하네요. 저는 아직 Workbox 랑 친하지 않아서 자세한건 잘 모르겠습니다..

정리

CRA v2 가 더욱 쓸만해진 것 같습니다. 아, 그리고 기존에 이미 CRA v1 로 프로젝트 작업 진행중이시고.. eject 하신 분들도 많을텐데요, 제 경험상 그런 경우는 CRA v2 로 프로젝트를 아예 새로 만드시고 거기에 기존 코드를 이동시켜서 오류나는 것들 수정하는 방식으로 진행하는게 가장 편할 것 입니다. 만약에 eject 안하셨다면 react-scripts 버전만 업그레이드 하시면 됩니다 :) (참고)

profile
CEO @ Chaf Inc. 사용자들이 좋아하는 프로덕트를 만듭니다.

28개의 댓글

comment-user-thumbnail
2018년 10월 2일

무언가 좀더 nuxt화 된거같네요! Nuxt의 장점을 도입한듯한.. 무튼 업데이트 되어 좋습니다~~ 자세한 글 감사합니다! :)

1개의 답글
comment-user-thumbnail
2018년 10월 2일

좋은 글 감사합니다! 많이 도움이 되네요!

1개의 답글
comment-user-thumbnail
2018년 10월 2일

잘읽었습니다. 다음 프로젝트에는 버전2 써볼려구요.
(블로그 플래폼 아주 멋있어요)

1개의 답글
comment-user-thumbnail
2018년 10월 2일

와 sass랑 svg! 애니메이션 같은 부분에 더 편하게 적용하는 법 고민해봐야겠어요. 다른 업데이트 내용도 와닿게 더 많이 만들어 봐야겠다는 생각도 드네요ㅎㅎ

답글 달기
comment-user-thumbnail
2018년 10월 2일

편리해진것들이 많네요. 좋은정보 얻어갑니다!

답글 달기
comment-user-thumbnail
2018년 10월 2일

좋은 글 감사합니다. 그럼 책에 있는 내용중 yarn eject랑 sass loader 부분은 생략해도 되는거네요.
따라해 보겠습니다.

답글 달기
comment-user-thumbnail
2018년 10월 3일

IE 최신버전도 지원안하는게 좀 파격적이네요 ㅎㅎ 내용 정리 감사합니다.

답글 달기
comment-user-thumbnail
2018년 10월 3일

좋은 정보 감사합니다!

답글 달기
comment-user-thumbnail
2018년 10월 6일

이전버전으로 설치할 수는 없나요 ㅠㅠ?

1개의 답글
comment-user-thumbnail
2018년 10월 7일

책 몇일 안봤더니 고세 업데이트 됐군요

답글 달기
comment-user-thumbnail
2018년 10월 7일

리다기를 보면서 eject하는 부분이 한번만 하면 되지만 그래도 조금 번거로울 수 있겠구나 했는데 개선이 되었군요.
좋은 내용 공유 감사합니다.
css module설정은 기존에 modules: true와 localIdentName 설정을 안해도 된다는 얘기인가요?

1개의 답글
comment-user-thumbnail
2018년 10월 8일

좋은 글 감사합니다.

답글 달기
comment-user-thumbnail
2018년 10월 9일

감사합니다. 9.1 CSS Module에서 막혀서 계속 찾아보고있었는데 이런 변화가있었네요!

답글 달기
comment-user-thumbnail
2018년 10월 9일

velopert 님 이번에 새로프로젝트를 만드면서 sass 부분을 설정해주지 않아도 되는건 편해졌지만
styles 폴더에서 utils.scss 파일을 상대경로로 불러오는 부분은 어떻게 추가해야하나요..? 고민이네요
기존의 webpack.config.dev.js 파일의 구조가 바뀌면서 제 나름대로 options 부분에 includePaths 를 설정하여 해보았지만 적용이 되지 않네요 ㅠㅠ 고민입니다..

1개의 답글
comment-user-thumbnail
2018년 10월 18일

좋은 글 감사합니다 !
정리가 잘 되어 있는 글이네요 ~

답글 달기
comment-user-thumbnail
2018년 10월 28일

책보다가 꽤 헤맸었는데 이렇게 또 업데이트를 해주셨군요 ㅠㅠ 정말 감사합니다!!
책보고 정말 즐겁게 리액트 공부하고 있습니다. 너무너무 고맙습니다!! :D

답글 달기
comment-user-thumbnail
2018년 11월 2일

많이 좋아졌네요 ㅋㅋㅋㅋㅋ

답글 달기
comment-user-thumbnail
2019년 1월 15일

잘읽었습니다. 울며겨자먹기로 eject하던 시절이 떠나갔군요

답글 달기
comment-user-thumbnail
2019년 2월 18일

리액트및 프론트 엔드 라이브러리는 거의 처음 인 입니다.
리액트를 다루는기술에서 yarn eject를 하면
webpack.config.dev.js 대신 webpack.config.js 가 있네요 ㅠ
17장 코드스플리팅을 제외한 파트는 CRA 2 가 더 편해서 오히려 좋았는데
코드 스플리팅할때나 장고랑 연동할때 같이 설정을 건드려 줘야할때는
webpack.config.dev.js 파일이 없고 webpack.config.js 를 건드리자니 책과 다른부분이 있어서 헤메고 있네요
eject 했을 때 config폴더 구성 변경, 17장 코드스플리팅을 CRA2에서 진행 할수 있는 내용도 변경사항 리뷰에 추가해주심 좋을것 같습니다.

답글 달기
comment-user-thumbnail
2019년 4월 2일

벨로퍼트님, proxy 설정 관련하여 질문이 한 가지 있습니다. 저도 docs에 따라 CRA v2 프로젝트에 src/setupProxy.js 파일을 만들고 그 안에다 http-proxy-middleware 라이브러리를 사용해 프록시 서버를 연결 했는데요, 이후 npm start를 하니 require(...) is not a function이라는 에러를 받았습니다.
뭔가 cra가 프록시 파일을 잡아서 연결하는 과정에서 오류가 나는 것 같은데요ㅠㅠ 벨로퍼트님은 웹팩이나 바벨의 추가 설정 없이도 그냥 바로 돌아갔었나요?
일단은 그냥 파일명을 다른걸로 바꾸고 터미널 하나 더 열어서 노드로 직접 서버를 돌려주면서 쓰고 있는데 원인을 알고싶네요ㅠㅠ 흑흑

답글 달기
comment-user-thumbnail
2019년 7월 11일

항상 좋은 강의 글 잘 보고 있습니다!!!

좋은 글에 왠 오타가... ㅠㅠㅠ < 웹팩 갸벌 >

답글 달기