Tetris Clone(1) : 사용된 재료 둘러보기

T

chvin/react-tetris는 만들어진지 벌써 4년이 넘었다. 그래서 여기에 사용된 플러그인/기술들중 현재 안쓰는것들이 많다. 하지만, 남이쓴 코드니까 제대로 분석하려면 어떤 플러그인들이 사용되었는지 그 재료들을 살펴볼 필요성을 느낀다.

사용되는 재료들

autoprefixer

자동으로 브라우저 전용 CSS접두어를 붙여준다. 예를들어서 내가 border-radius: 10px; 으로 CSS를 작성하면

-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-o-border-radius: 10px;
-ms-border-radius: 10px;
border-radius: 10px;

위와같이 모든 브라우저에서 border-radius가 잘 적용되도록 접두어를 자동으로 붙여준다.

babel-core

여기 참고

Babel은 (예를들어) ES6문법으로 작성한 JS코드를 ES3문법으로 바꿔주는 역할을 한다. 근데 이 Babel은 v6에 들어오면서 babel-core와 babel-cli로 나뉘어졌다. babel-core는 Node API를 사용해서 코드변환을 하고, babel-cli는 command-line에서 코드변환을한다.

Node API를 사용한다는건 어떤 의미인가?... 대충 아래와 같다.

require("@babel/core").transform("code", {
  plugins: ["@babel/plugin-transform-react-display-name"]
});

babel-loader

내 코드를 읽고 합치고 하는거는 결국 Webpack이 주관한다. 그래서 Webpack한테 "js파일을 만나면 Babel한테 변환하는 일을 맡겨줘" 라는 의미로 babel-loader를 설치해준것이다. 이 loader가 있어야 Webpack이 내 코드를 Babel을 사용해서 변환한다.

babel-plugin-react-transform

현재는 react-hot-loader로 대체되었다.

코드를 수정하고 저장하면 알아서 새로고침이 된다. 물론 webpack-dev-server 만 있어도 알아서 코드를 수정하면 새로고침이 되었지만, 컴포넌트의 state는 저장되지 않는 문제가 있다. react-hot-loader는 컴포넌트의 state를 유지한채 코드의 변경점을 자동으로 반영해준다.

현재는 react-hot-loader에서 더 나아가서 react-fast-refresh로 넘어가고있다.(아직은 실험단계)

babel-preset-es2015

Babel은 Babel용 Plugin이 없으면 아무일도 하지 않는다.

Note

Babel is a compiler (source code => output code). Like many other compilers it runs in 3 stages: parsing, transforming, and printing.
Now, out of the box Babel doesn't do anything. It basically acts like const babel = code => code; by parsing the code and then generating the same code back out again. You will need to add plugins for Babel to do anything.

플러그인의 목록은 여기서 찾아볼 수 있다. 하지만 이런 플러그인들을 일일이 다 설치해 주는건 귀찮으니까, preset(미리 모아놓은 세트)으로 한방에 플러그인들을 설치하는것이다.

지금은 그냥 @babel/preset-env을 쓰면 된다.

babel-preset-react

JSX는 브라우저가 지원하는 문법이 아니다. 그래서 JSX문법으로 작성된 코드를 브라우저가 알아먹도록 react 함수로 변환해주는 역할을하는 플러그인이 내장되어있다.

대충 이런느낌

In

const profile = (
  <div>
    <img src="avatar.png" className="profile" />
    <h3>{[user.firstName, user.lastName].join(" ")}</h3>
  </div>
);

Out

import { jsx as _jsx } from "react";
import { jsxs as _jsxs } from "react";

const profile = _jsxs("div", {
  children: [
    _jsx("img", {
      src: "avatar.png",
      className: "profile",
    }),
    _jsx("h3", {
      children: [user.firstName, user.lastName].join(" "),
    }),
  ],
});

copy-webpack-plugin

어떤 디렉토리에있는 파일들이나 디렉토리 자체를 webpack을 실행할때 다른 디렉토리로 복붙한다. 근데 이게 왜 필요할까?

웹팩으로 (file-loader를 사용해서) 이미지를 번들링하면 새로운 이미지가 만들어진다. 원본 이미지는 냅두고 bundle 디렉토리에 그 이미지를 복사해서 넣어놓는다.

nike.jpg와 95ee4e...jpg 파일은 같은 파일이다

자세한건 여기를 참고!

css-loader

Webpack이 CSS파일을 처리할 수 있도록 한다. 내가 CSS파일안에 @importurl(...) 을 쓰면 이거를 마치 import나 require처럼 처리해준다. 다만, 이렇게 처리된 결과물을 string으로 받아놓는것 밖에 안하기 때문에 화면에 CSS를 반영하기 위해서는 style-loader가 필요하다.

자세한건 여기를 참고!

eslint

내가 코드를 이상하게 쓴거를 잡아준다. 이상하게 썼다는거는 문법적으로 문제가 있는 코드를 썼다는 의미와 지정된 코딩스타일을 따르지 않았다는 의미도 포함한다.

eslint-config-airbnb

airbnb에서 사용하는 코딩스타일 규칙이 담겨있다.

eslint-loader

내 코드를 싸그리 읽어서 한덩어리로 촥 만드는거는 Webpack이 주관하기 때문에, eslint가 낄 틈을 만들어주기 위해서 eslin-loader가 필요하다. 즉, 이 loader를 통해서 Webpack이 ESLint를 사용할수 있게된다.

eslint-plugin-import

ES2015부터 생긴 import/export 기능을 쓸때, 문법적으로 문제가 없이 잘 썼는지를 검사해준다.

eslint-plugin-jsx-a11y

내가 쓴 JSX문법이 웹접근성 규칙을 잘 지켰는지를 검사해준다.

eslint-plugin-react

React코딩을 할때 규칙을 잘 지켰는지 검사를 해준다. 어떤 규칙을 지켜야 하는지는 여기를 참고하자.

extract-text-webpack-plugin

CSS파일을 import하면 보통 bundle.js파일안에 적히거나, html파일 안에 <style>태그 사이에 들어가도록 하는데, 따로 .css파일로 빼낼때 이 플러그인을 쓴다. 하지만! 지금은 mini-css-extract-plugin를 쓴다.

file-loader

이거를 참고하자.

html-webpack-plugin

HTML 파일을 후처리하는데 사용한다.

자세한건 여기를 참고.

json-loader

json 파일을 import할때 쓰인다. 하지만 현재는 기본적으로 되기 때문에 쓸필요없다.

less

CSS 전처리 프로그램. CSS작성할때 변수도 쓰고 뭐도 쓰고 할수있다. 근데 나는 개인적으로 Sass가 더 좋다.

less-loader

less파일을 import할때 쓰인다.

open-browser-webpack-plugin

Webpack으로 빌드하고 나서 자동으로 브라우저가 그 파일들을 읽어들이도록 한다. 하지만 이거는 webpack-dev-server를 쓰면 되니까 실상 필요도 없고, 이젠 관리도 안되고있다.

postcss

참고 사이트

autoprefixer등의 유용한 CSS관련 플러그인들을 쓰려면 필요하다.

postcss-loader

PostCSS로 CSS코드를 처리하기 위한 Loader이다

precss

CSS를 Sass처럼 쓸 수 있게 해주는 라이브러리이다.

react-transform-hmr

위에서 설명한 babel-plugin-react-transform 과 세트로 사용한다. 둘이 어떻게 세트로 작동하는지는 모르겠지만, Hot Module Replacement기능을 쓰기 위해서 필요했었나보다. 지금은 안쓴다.

style-loader

css-loader와 같이 사용한다. css-loader로 읽어들인 css string을 index.html 파일 안의 <head> 안에 <style> 요기 <style> 에 넣는다. 결과적으로 아래와 같은 코드가 생성된다.

<html>
    <head>
        <!-- this tag was created by style-loader -->
        <style type="text/css">
            body {
                background: yellow;
            }
        </style>
    </head>
    <body>
        <script type="text/javascript" src="bundle.js" charset="utf-8"></script>
    </body>
</html>

url-loader

작은 이미지나 글꼴의 파일을 Base64형태의 문자열로 바꿔서 바로 번들 파일에 넣어버린다. 이렇게 하면 HTTP Request가 줄어들어서 페이지 로딩이 더 빨라지는 장점이 있다. (참고 사이트)

webpack

다양한 파일들을 번들링해준다.

webpack-dev-server

계속 수동으로 번들링하면 시간도 오래걸리고 불편해서 만들어졌다. 개발서버를 만들어주고 코드에 변화가 있을때 알아서 빠르게 번들링 해주고 브라우저에 반영된다.

classnames

리액트 컴포넌트에 클래스 이름을 지정할때 사용한다. HTML에서 element에 class = "main box" 했던것 처럼 리액트 컴포넌트에는 <div className={classNames('main', 'box')} 이런식으로 사용한다.

immutable

객체의 불변성을 편하게 유지할때 쓰는 라이브러리(immutable.js)이다. 근데 꼭 이거 안써도 ES6에서 지원하는 Object.assign(..), Object.freeze(..) 등을 써도 된다. 하지만 immutable보다는 ImmerRedux-Toolkit 을 쓰는게 더 좋을것같다.

prop-types

리액트 컴포넌트에 적용되는 속성(Property)의 타입을 지정할 수 있다. Javascript는 타입을 강제할 수 없는 특징이 있는데, 컴포넌트의 속성이 많아지다보면 그 컴포넌트를 사용하는데 있어서 실수가 발생한다. 참거짓을 넣어야 하는데 0을 넣어서 (의도치않게) 작동하는 등의 문제가 있을것이다. 그래서 prop-types를 써서 속성의 타입을 강제할 수 있다.

하지만 나는 그냥 Typescript를 쓰는걸 선호한다.

qrcode

QRcode 컴포넌트를 만들어주는 라이브러리이다

react

어떤 이벤트에 따라서 변화가 많은 웹앱을 개발할때 도움을 준다. 기존의 방식대로 HTML + CSS + JS만 쓰면 코드가 엄청 복잡해지고 관리하기가 힘들어지는데, React를 쓰면 그나마 좀 편해진다.

react-dom

React Component들을 담는 React용 DOM을 제공한다. 우리가 만드는 모든 컴포넌트들은 이 DOM에 담기게 되며, React DOM이 실제 브라우저에 그려준다. 원래는 react라이브러리안에 들어있었으나 지금은 페이스북이 분리해서 관리하고 있다.

redux

컴포넌트의 상태를 좀 더 일관된 방식으로 관리하기 쉽게 만들어준다. 물론 작성해야할 코드는 더 길어지지만, 쓰는게 좋다.

react-redux

redux는 꼭 react랑만 써야하는 라이브러리가 아니다. react랑 쓸때는 react-redux 가 필요하다.

redux-immutable

redux와 immutable.js를 같이 사용하려고 할때 필요한 라이브러리

마무리

이렇게 chvin/react-tetris 에 사용된 모든 라이브러리들을 살펴보았다. 설명이 충분하지 못한 부분도 있지만, 일단 이정도만 알고 넘어가자! (귀찮..)

Add Comment