블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2015. 8. 23. 17:48 React

Semantic UIReact 컴포넌트로 만들고 NPM 저장소와 Meteor 저장소인 Atmosphere에 배포해 보자. 토요일 헤커톤 모임을 갖고 스마트링크 멤버분들과 함께 진행했다. 목표는 React Bootstrap 과 같은 오픈소스 패키지를 만들어 보는 것이다. 처음엔 활짝 웃고 있는 모습!







준비 운동 


함께 개발을 진행하는 관계로 코딩 컨벤션은 에어비엔비의 React 코드 컨벤션으로 한다.  다음으로 깃헙(GitHub) 저장소를 만들었다. 소셜 코딩은 역시 깃헙이다. 깃을 사용하므로 커밋 메세지를 잘 작성하면 별도의 CHANGELOG를 작성할 필요가 없다. 따라서 Git Commit에 대한 컨벤션도 앵귤러에서 사용하는 방식을 쓴다. 그리고 정보를 찾고 공유하는 것은 슬랙(Slack)을 이용하고, 할일에 대한 보드는 트렐로(Trello)를 이용해 서로 공유하고 있다. 트렐로를 슬랙과 연동하면 슬랙에서 모든 것을 확인 할 수 있다. 


일단 npm 초기화을 초기화하고 모듈을 설치한다.  package.json 에 설치하는 모듈은 다음과 같다. 

  - ES6를 사용하기에 Babel을 통해 ES5로 트랜스파일한다. 

  - React로 설치하고, classnames는 리액트 코드안에서 클래스명을 확장해 주는 기능을 한다. 

  - fbjs는 ES7의 dectorator를 사용해 React Start Kit에 있는 withStyle을 컴포넌트별로 적용해 보려 했으나 원하는 동작이 안된다. 제거해도 좋음. 

  - *-loader는 웹팩(Webpack)을 통해 전체 패키지를 하나의 배포 파일로 번들링하기 위해 설치한다. 

package.json에 설정을 넣고 한번에 npm install 해서 설치하자

// package.json 일부 내역 


"dependencies": {

  "babel": "^5.8.21",

  "react": "^0.13.3",

  "classnames": "^2.1.3",

  "fbjs": "0.1.0-alpha.7"

},

"devDependencies": {

  "babel-core": "^5.8.22",

  "babel-loader": "^5.3.2",

  "css-loader": "^0.15.6",

  "fbjs": "0.1.0-alpha.7",

  "semantic-ui-css": "^2.0.8",

  "style-loader": "^0.12.3",

  "url-loader": "^0.5.6",

  "webpack": "^1.11.0"

}

 

다음으로 웹팩 환경파일인 webpack.config.js 를 만든다.  웹팩은 사전에 설치할 것이 있는데 홈페이지의 Getting start를 보자. 그리고 어떻게 잘 사용할지는 페북 엔지니어인 피트헌트의 Webpack Howto를 참조한다. 설정 내용은 다음과 같다. 

  - 배포 파일 명칭은 reactjs-semantic-ui.js 파일이고, /src/index.js 파일에 모든 참조 내역을 작성한다. 

  - 배포시 접근하는 네임스페이스는 RSU (React Semanctic Ui) 이다. 예로 본 패키지를 리액트 코드에서 사용하면 RSU.Button 식의 접근이다. 

  - .js 또는 .jsx 확장자는 babel-loader로 ES6를 ES5로 트랜스파일한다. 

  - 웹팩은 css 파일과 이미지 파일도 함께 번들링 하므로 style-loader 와 css-loader를 설정하고, 이미지와 폰트 관련해서 url-loader를 설정한다. 

  - react.js 관련 파일은 웹팩으로 번들링시에 제외토록 externals를 설정한다. 

// webapck.config.js 내역 


module.exports = {

entry: {

'reactjs-semantic-ui': './src/index.js'

},

output: {

path: './dist',

filename: '[name].js',

library: 'RSU',

libraryTarget: 'umd'

},

module: {

loaders: [

{

test: /\.jsx?$/,

exclude: /(node_modules|bower_components)/,

loader: 'babel-loader'

                       },

{

test: /\.css$/,

                                exclude: /\.useable\.css$/,

loader: 'style-loader!css-loader'

},

{

test: /\.(png|jpg|svg|eot|woff|woff2|ttf)$/,

loader: 'url-loader?limit=8192'

} // inline base64 URLs for <=8k images, direct URLs for the rest

                ]

},


externals: [

          {

              'react': {

                   root: 'React',

                   commonjs2: 'react',

                   commonjs: 'react',

                   amd: 'react'

             }

         }

     ]

}


Babel 사용시 주의 점은 간혹 ES7 의 decorator를 사용하거나 특정 스펙 레벨까지 적용하고 싶다면 루트에 .babelrc를 생성하고 stage를 설정해야 한다. stage 설정 가이드를 참조하자.

{

    "stage" : 0

}




 

개발 시작


환경 준비하며 문제점을 해결하는데 3시간 가까이 소비를 했다. 본격적으로 시멘틱 UI를 리액트화 하기 위해 다음과 같은 순서로 작업을 한다. 

  - src/index.js안에 작성한 컴포넌트들을 설정한다. 

  - 시멘틱 UI가 구분해 놓은 Elements, Collections, Views ... 와 같이 구분해서 폴더를 만들어 그밑으로 컴포넌트를 만든다. 

  - 시멘틱 UI의 core css는 reset.css 로 Reset 클래스를 하나 만들었다. 

  - ES6 구문을 사용한다. ES5 Features를 참조하자 

    + import ... from 

    + { key : value } 가 동일 설정이면 { key1, key2 }로 나열 

    + export default RSU 

// Globals
import Reset from './globals/Reset';

// Elements
import { Button, Buttons } from './elements/Button';
import Container from './elements/Container';
import Dimmer from './elements/Dimmer';
import Divider from './elements/Divider';
import Flag from './elements/Flag';
import Header from './elements/Header';
import Icon from './elements/Icon';
import Image from './elements/Image';
import Input from './elements/Input';
import Label from './elements/Label';
import { List, Item } from './elements/List';
import Loader from './elements/Loader';
import Rail from './elements/Rail';
import Reveal from './elements/Reveal';
import Segment from './elements/Segment';
import { Step, Steps } from './elements/Step';

// Collections
import Breadcrumb from './collections/Breadcrumb/Breadcrumb';
import BreadcrumbDivider from './collections/Breadcrumb/BreadcrumbDivider';
import BreadcrumbSection from './collections/Breadcrumb/BreadcrumbSection';
import Form from './collections/Form/Form';
import Grid from './collections/Grid/Grid';
import Column from './collections/Grid/Column';
import Row from './collections/Grid/Row';
import Menu from './collections/Menu/Menu';
import Message from './collections/Message/Message';
import Table from './collections/Table/Table';

// Views
import Card from './views/card/Card';
import CardImage from './views/card/CardImage';
import CardContent from './views/card/CardContent';
import CardHeader from './views/card/CardHeader';
import CardMeta from './views/card/CardMeta';
import CardDescription from './views/card/CardDescription';

const RSU = {
    // Elements
    Button, Buttons,
    Container,
    Dimmer,
    Divider,
    Flag,
    Header,
    Icon,
    Image,
    Input,
    Label,
    List, Item,
    Loader,
    Rail,
    Reveal,
    Segment,

    Step, Steps,

    // Views
    Card,
    CardImage,
    CardContent,
    CardHeader,
    CardMeta,
    CardDescription,

    // Collections
    Breadcrumb,
    BreadcrumbDivider,
    BreadcrumbSection,
    Form,
    Grid,
    Row,
    Column,
    Menu,
    Message,
    Table
}
 

export default RSU;


리액트 컴포넌트는 다음과 같이 만든다. 1주차엔 시멘트 UI의 css를 적용해서 잘 나오는지만 확인하는 것으로 리액트 컴포넌트의 라이프사이클 메소드를 전부 설정해서 넣는다. 

  - 어빈앤비의 리액트 코딩 컨벤션에 따라 작성한다. 

  - shouldComponentUpdate 구문은 향후 Immutable.js 사용과 PureRenderMixin의 조합을 고려해 성능을 향상시켜야 한다. 

    이에 대한 좋은 글이 있으니 꼭 읽어보자.  Immutable.js에 대한 연재글 [1], [2], [3]

  - 리액트의 라이프 사이클 코드가 대부분의 컴포넌트에 중복해서 들어 있으므로 이것도 ES6 구문을 위한 리액트의 Mixin 패키지를 사용해 리팩토링해야 한다.

  - classNames( x, y, this.props.className )은 classnames 패키지를 사용해서 <Card className="ui card <상속 className>"> 을 설정해 준다.  

  - <div {...this.props} 를 하면 상위에 설정한다. 모든 key="value" 애트리리뷰트를 그대로 설정해준다. 단, 주의 점은 <div {...this.props} className...> 처럼 사용하면 className은 오버라이딩 된다는 점이다. 만일 <div className={componentClass} {...this.props}> 로 하고 <Card className="dowon" /> 를 사용하면 className={componentClass} 는 적용이 되지 않는다. 즉 태그안에서 중복된 키이면 뒤에 놓은 것으로 설정이 덮어써진다.

import React, { Component, PropTypes } from 'react';
import card from 'semantic-ui-css/components/card.css';
import classNames from 'classnames';

const propTypes = {
	className: PropTypes.string,
};

const defaultProps = {
	className: ''
};

class Card extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  };

  componentWillMount() {};
  componentDidMount() {};
  componentWillReceiveProps(nextProps) {};
  shouldComponentUpdate(nextProps, nextState) {
    return true;
  };
  componentWillUpdate(nextProps, nextState) {};
  componentDidUpdate(prevProps, prevState) {};
  componentWillUnmount() {}

  render() {
    var componentClass = classNames(
      'ui',
      'card',
      this.props.className
    );

    return (
      <div {...this.props} className={componentClass}>{this.props.children}</div>
    )
  };
}

Card.propTypes = propTypes;
Card.defaultProps = defaultProps;
 

export default Card;


학학 다들 컴포넌트 만드는데 저녁 7시를 치닫고 있다. 아 나만 힘들어...






테스트 하기 


만들어진 컴포넌트를 테스트하기 위해 src 폴더 외에 docs 폴더를 만들어 예제를 만든다. 

  - 시멘틱 UI 처럼 폴더 구조를 가지고 각각 index.html파일을 만든다. 

  - 패키지를 사용하는 입장이기 때문에 react.min.js를 넣고 테스트용이기 때문에 <script type="text/jsx;harmony=true"> 해석을 위해 JSXTransformer도 넣었다.

  - 테스트 코드는 Card.js 이면 CardExample.js 로 해서 작성한다. 

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title> Reactjs Semantic Ui </title> </head> <body style="margin-left: 20px; margin-top: 20px;"> <div id="app"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script> <script src="../../dist/reactjs-semantic-ui.js"></script> <script type="text/jsx;harmony=true" src="./CardExample.js"></script> <script type="text/jsx;harmony=true"> // Card React.render( <CardExample />, document.getElementById('app') ); // </script> </body> 

</html>


CardExample.js를 다음과 같다. 

  - import 구문이 안먹는다. 이유 아는분 메세지 좀 주세요. 그래서 render안에 RSU 네임스페이스 제거하고 사용한다. 

  - Card 관련 <div class="xxx"> 설정을 리액트 컴포넌트로 만들어 사용해 본것이다. 

// import { Card, CardImage, CardContent, CardHeader, CardMeta, CardDescription } from 'RSU';

class CardExample extends React.Component {

  render() {
    var Card = RSU.Card,
        CardImage = RSU.CardImage,
        CardContent = RSU.CardContent,
        CardHeader = RSU.CardHeader,
        CardMeta = RSU.CardMeta,
        CardDescription = RSU.CardDescription

    return (
      <div>
        <h3><a href="http://semantic-ui.com/views/card.html" target="_blank">Card</a></h3>
        <Card>
          <CardImage onClick={Alert} src="../assets/images/kristy.png" />
          <CardContent>
            <CardHeader desc="Kristy" />
            <CardMeta>
              <span className="date">Joined in 2013</span>
            </CardMeta>
            <CardDescription>
              Kristy is an art director...
            </CardDescription>
          </CardContent>
          <CardContent className="extra">
            <a>
              <i class="user icon"></i>
              22 Friends
            </a>
          </CardContent>
        </Card>
      </div>
    );
  }
 

}


이제 테스트를 위해 "npm install -g webpack-dev-server"를 설치하고 실행한다. 실행은 소스 루트에서 한다. 

  - 호출은 http://localhost:8080/docs/views 로 직접 경로를 지정한다. 

$ webpack-dev-server --progress --colors

  0% compilehttp://localhost:8080/webpack-dev-server/

webpack result is served from /

content is served from /Users/yunyoungsik/mobicon/open-sources/unplugdj/src/reactjs-semantic-ui

Hash: 0d552960154cf0b24cf3

Version: webpack 1.11.0

Time: 2759ms

                 Asset    Size  Chunks             Chunk Names

reactjs-semantic-ui.js  113 kB       0  [emitted]  reactjs-semantic-ui

chunk    {0} reactjs-semantic-ui.js (reactjs-semantic-ui) 110 kB [rendered]

    [0] ./src/index.js 418 bytes {0} [built]

    [1] ./src/elements/Button.js 4.6 kB {0} [built]

    [3] ./~/semantic-ui-css/components/button.css 870 bytes {0} [built]

    [4] ./~/css-loader!./~/semantic-ui-css/components/button.css 87.5 kB {0} [built]

    [5] ./~/css-loader/lib/css-base.js 1.51 kB {0} [built]

    [6] ./~/style-loader/addStyles.js 6.09 kB {0} [built]

    [7] ./src/utils/withStyles.js 3.86 kB {0} [built]

    [8] ./~/fbjs/lib/invariant.js 1.51 kB {0} [built]

    [9] (webpack)/~/node-libs-browser/~/process/browser.js 2.02 kB {0} [built]

   [10] ./~/fbjs/lib/ExecutionEnvironment.js 1.09 kB {0} [built]

     + 1 hidden modules

webpack: bundle is now VALID.


결과화면이다. 예들 상단에 시멘틱 UI쪽에 관련 링크를 걸기로 한다. 


앞으로 시멘틱 UI의 자바스크립트 코드를 리액트에 넣고 나머지 부분을 컴포넌트화 해야 한다. 그리고 성능 향상과 중복 코드 제거를 위한 Mixin을 이용한 리팩토링이 필요하다. 그 후엔 패키지 배포. 다음 시간에 다시 2차 헤커톤을 진행하기로 하고 저녁 10시에 종료! 




To Be Continue...

'React' 카테고리의 다른 글

[React] 다시 시작하기  (0) 2018.09.14
[React] CSS Framework 선정하기  (0) 2015.08.15
[Flux] Flux 배우는 방법  (0) 2015.07.04
[React] AngularJS와 ReactJS 비교  (0) 2015.07.01
[React] 배우는 방법  (0) 2015.05.15
posted by 윤영식
2015. 8. 15. 12:26 React

서비스를 개발할 때 만들어 놓은 CSS 프레임워크를 사용한다면 보통 트위터 부트스트랩을 많이 선택한다. 앵귤러 프레임워크를 사용할 때 트위터 부트스트랩을 앵귤러 컴포넌트로 만들어 놓은 모듈을 사용하는데, 리액트에서는 어떤 것을 사용할 수 있는지 정리해 보자. 




트위터 부트스트랩

http://react-bootstrap.github.io/

  + v1.0.0 이 릴리즈 되었다. 

  + 부트스트랩의 기능을 충실히 구현




머터리얼 디자인

http://material-ui.com/

  + 구글의 머터리얼 디자인을 충실히 구현

  + 모바일 first 디자인




그외 프레임워크 

http://elemental-ui.com/

  + 가장 기본적인 부분들을 리액트 컴포넌트로 제공


http://nikgraf.github.io/belle/

  + elemental-ui와 유사


http://semantic-ui.com/

  + 리액트 컴포넌트로 만들어져 있지 않지만 앞으로 만들어 보고 싶은 css 프레임워크

  + v1.* 보다 다양한 실용적인 Theme을 제공하고, 컴포넌트가 다양하다. 

  + 향후 직접 React UI Component로 만들어 사용할 예정!





모바일 전용 프레임워크 

http://touchstonejs.io/

  + ionic 의 css 와 유사하게 native 느낌을 준다. 





<참조>

- 리액트 12가지 css 프레임워크

- 리액트로 만든 관리자 화면 예제 : ClojureScript를 사용해서 React 컴포넌트를 개발했음

- 다양한 React UI Components 목록



'React' 카테고리의 다른 글

[React] 다시 시작하기  (0) 2018.09.14
[React] Semantic-UI를 React 컴포넌트로 만들기 - 1  (0) 2015.08.23
[Flux] Flux 배우는 방법  (0) 2015.07.04
[React] AngularJS와 ReactJS 비교  (0) 2015.07.01
[React] 배우는 방법  (0) 2015.05.15
posted by 윤영식
2013. 11. 27. 14:37 HTML5, CSS3/CSS

개발자들이 서비스를 만들면서 어렵게 여기는 부분이 디자인이다. 특히 웹 서비스를 만들라 치면 어디서 부터 시작해야 할지 난감할 때가 있는데 이를 해소하고자 CSS Framework를 오픈소스로 제공하는 업체들이 늘어나고 있다. 가장 유명한 Twitter Bootstrap 부터 Pure까지 그 종류도 많은데 어떤 것들이 있는지 정리해 본다. 정리하면서 느끼는 것은 Bootstrap을 확장한 framework인 Bootflat, Maxmertkit같은 것이 좀 더 다양한 느낌의 모듈을 제공하고, Metro UI스타일의 Flat 디자인을 언젠가 꼭 써보고 싶다. 그리고 GroundWork, Foundation, Pure 도 테스트해 볼 필요가 있겠다. 그외의 웹 모듈은 선택한 CSS Framework에 Add할 수 있는지 확인 후 쓰면 되겠다 



Twitter Bootstrap

  - http://getbootstrap.com/

  - CSS 화면 레이아웃과 스타일 제공

  - 화면 구성을 위한 jQuery 접목된 JavaScript 컴포넌트 제공 

  - RWD (반응형 웹디자인) 제공 : RWD 25개 도구들

  - 다양한 곳에서 많이 사용하나 개인적으로 색감이 이젠 식상할 때가 된 듯함

  - Bootstrap 확장 툴박스들 소개  그외 정리한 툴들 (강추)

  - OpenTutorial 동영상으로 배우기

  - Bootstrap v3 으로 화면 만들기

  - 다양한 도구와 컴포넌트 목록 *강추

  - BootStrap Theme 바꾸는 방법




Semantic UI

  - http://semantic-ui.com/

  - Bootstrap같은 기계적인 용어보단 인간친화적인 CSS Class 명칭

  - 좀 더 상업적인 UI 제작에 필요한 다양한 웹 모듈 제공

  - 개인적으로 인간친화적인 따뜻한 색감을 좋아함




Zurb Foundation 

  - http://foundation.zurb.com/

  - 다양한 화면 레이아웃 템플릿 제공으로 빠른 포로토타입핑 가능

  - RWD 제공

  - 웹서비스 페이지 만들기 적합




BootSnipp

  - http://bootsnipp.com/

  - Bootstrap에서 사용하는 코드 템플릿 제공

  - 다른 Template 리소스 사이트들



Start Bootstrap Template

  - http://startbootstrap.com/

  - template을 가지고 시작해 보자 

  - BootPlus에서도 제공함 

  - CodeStrap 또 다른 변형

  - http://bootswatch.com/ 에서는 다양한 Theme 색감의 bootstrap 선택가능



Bootflat

  - http://www.flathemes.com/

  - Bootstrap v3.0 확장판이다 

  - Bootstrap css 파일과 확장된 css를 링크하므로 Bootstrap에서 모자란 부분을 보완할 수 있다

  - https://wrapbootstrap.com/ 의 테마들처럼 Bootstrap 확장 느낌이 난다 



BootPlus

  - http://aozora.github.io/bootplus/

  - Bootflat과 유사한 기능을 제공

  - CSS의 느낌을 좀 더 간결하게 표현함 



FlatStrap

   

  - http://flatstrap.org/index.html

  - Bootflat과 유사함 



LeapStrap

  - http://wilkesalex.github.io/leapstrap/

  - touch smart device 고려 



FuelUX

  - http://exacttarget.github.io/fuelux/

  - Bootstrap 스타일의 다양한 컨트롤러 



PixelKit 

  

  - http://pixelkit.com/

  - 프리미엄 UI Kits 을 Theme별로 제공을 한다 

  - 예제 Sweet Candy

  - 소스 : https://github.com/Pixelkit/PixelKit-Bootstrap-UI-Kits

  - 상용이다 



Maxmertkit

  - http://www.maxmert.com/

  - Bootstrap 과 유사한 느낌을 전달 CSS class가 항시 "-" 또는 "_"로 시작하여 다른 CSS Framework와 충돌방지 

  - Bootflat에서 제공하지 않는 3D 적인 디자인과 효과 좋음 

  - Bootstrap css 파일과 혼용하여 사용할 수 있는지 체크 필요



Metro UI CSS

  - http://metroui.org.ua/

  - MS의 Metro Flat 디자인 제공

  - Bootstrap에서 느끼지 못하는 깔끔함이 있음 

  - RWD 제공




GroundWork

  - http://groundwork.sidereel.com/

  - 웹페이지, 이미지 겔러리, 커머스사이트 레이아웃 예제 제공

  - 다양한 화면사이즈에 대한 테스트 제공 (RWD)

  - 개인적으로 좋아하는 약간 따뜻한 색감 

  - 웹 모듈은 많지 않고 다른 UI 툴과 연계해서 사용하면 좋을 듯함



Pure

  - http://purecss.io/

  - Yahoo 에서 만듦

  - 사이즈 작고 flat한 디자인으로 간결한 맛이 있음 



Ink v.2

  - http://ink.sapo.pt/

  - 빠르게 웹 인터페이스를 개발할 수 있는 툴이다 

  - RWD 제공

  - Bootstrap과 거의 유사

  - Drap 컴포넌트 제공 



UIKit

  - http://getuikit.com/

  - 30가지의 UI 모듈을 제공

  - 다른 CSS Framework엔 없는 효과를 준 모듈 존재



Amazing Web Library

  - http://a-web.me/

  - UIKit과 유사하지만 차트와 그리드에 대한 부분이 강력함 




Brick

  - http://mozilla.github.io/brick/

  - 모질라에서 제공

  - 모바일에 특화된 UX적인 효과 제공

  - 모바일 예제 데모를 충실히 보여줌 



MicroJS

  - http://microjs.com/ (강추)

  - 다양한 웹 컴포넌트 검색 

  - 파일 크기 명시



<참조>

  - 원문 : 10 Free UI Kit

  - 원문 : 18개의 CSS Framework

  - 50개의 Web Developer를 위한 리소스와 툴들

  - Twitter Bootstrap v3 이해하기

  - Yahoo Pure에 대하여

  - HTML5 free Layout Template을 얻고 싶다면

  - UI Kit Maker

  - 유용한 CSS 도구들 (필독)

posted by 윤영식
prev 1 next