[React.JS] Tip: Webpack css-loader 를 통하여 .css 파일을 import 하여 사용하기


이 포스트는 살짝 outdated 되었습니다. 새로 작성된, 리액트 컴포넌트 스타일링 – CSS Module / Sass / styled-components 포스트를 읽는것을 권고합니다.

 

기본적으로는, React.js 컴포넌트의 스타일을 설정 할 땐, Inline Styles 를 사용합니다. style 을 JavaScript 객체형으로 만들어서 사용하는 것이죠

물론, 이 외의 방법으로는 HTML 파일에서 따로 CSS 를 불러오거나,
rendering 부분에 <style> 태그를 삽입하여 className 을 입력하는 방법도 있습니다.

위 방법들은 장단점이 좀 있죠. 편한 대신에, 코드 유지가 조금 번거로워집니다.

 

이번 포스트에서는, webpack 을 사용하는 React.js 프로젝트 작업환경에서
컴포넌트 파일에서 CSS 파일을 직접 import ( 혹은, require ) 하여 사용하는 방법을 알아보겠습니다.

 

시작하기전에

webpack 을 사용하여 React.js 작업환경을 만드세요. 이에 대한 정보는 강좌 2편 작업환경 설정하기 에 있습니다.

 

의존 모듈 설치하기

$ npm install --save-dev style-loader css-loader

필요한 모듈은 style-loadercss-loader 입니다.

 

webpack.config.js 파일에 loaders 추가하기

    loaders: [
        {
            test: /\.js$/,
            loader: 'babel',
            exclude: /node_modules/,
            query: {
                cacheDirectory: true,
                presets: ['es2015', 'react']
            }
        },
        {
          test: /\.css$/,
          loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
        }
    ]

webpack.dev.config.js 를 사용하는 경우엔 해당 파일에도 위 로더를 추가하세요.

디렉터리 구조

src
├── components	
│   ├── App
│   │   ├── App.css
│   │   └── App.js
│   └── index.js        # LOADS COMPONENT(S) AND EXPORTS IT
└── index.js            # ENTRY POINT

먼저, 디렉토리 구조를 알아봅시다.

꼭 이런 디렉토리 구조를 따를 필요는 없지만, 어떤 방식으로든, 편하고 보기 좋은 디렉토리 구조를 사용하는것을 권장합니다.

 

각 컴포넌트마다 components 디렉토리에 새 디렉토리를 만들고, 그 디렉토리에 js 파일과 css를 저장합니다.

그리고, components/index.js 에서 다음과 같이 components 에 있는 컴포넌트를 불러오고 export 합니다.

import App from './App/App'

export { App }

컴포넌트를 더 만들게 된다면 import 코드를 하나 더 추가시키고, export 부분에 { App, Button } 이런식으로 객체에 추가해줍니다.

 

이렇게 export 한 컴포넌트들은 사용 할때 다음과 같이 사용합니다.

import ReactDOM from 'react-dom';
import React from 'react';

import { App } from './components';


const rootElement = document.getElementById('root');

ReactDOM.render(<App/>, rootElement);

이렇게 하면 컴포넌트가 몇개가 됐든, 한줄로 불러 올 수 있습니다.

 

예제 CSS 파일 만들기

App 컴포넌트를 위한 CSS 파일을 components/App/App.css 에 저장하겠습니다.

.container {
    position: fixed;
    width: 100%;
    height: 100%;
    background-color: black;
}

.hello {
    color: white;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 3rem;
}

 

예제 컴포넌트에 CSS 파일 import 후 클래스 사용하기

import React from 'react';
import styles from './App.css';

export default class App extends React.Component {
    componentWillMount() {
        document.body.style.margin = 0;
        document.body.style.padding = 0;
    }

    render() {
        return (
            <div className={styles.container}>
                <div className={styles.testing}>
                    hello
                </div>
            </div>
        );
    }
}

 

결과보기

이미지 2

간단했죠? 비슷한 방식으로, sass 로더를 설정하면 sass 를 불러와서 사용 할 수 있습니다.

현재 sass 튜토리얼을 준비중입니다. 그 튜토리얼이 작성 완료되면 React.js 에서 sass 를 사용하는 방법을 알아보도록 하겠습니다.

  • Changsoo Yoon

    요 방식으로 여러개는 어떻게 하나요? A이자 B도 되어서 class=”A B” 이듯이 A라는 CSS와 B라는 CSS가 동시에 먹게 하는 방법을 모르겠네요.. 자꾸 뒤에거 하나만 먹어요.

    • classnames 라는 모듈을 사용해보세요.
      npm 을 통해 설치하고,

      className={classnames(‘foo’, ‘bar’, style.foo)} 이런식으로 사용 할 수 있답니다.

      다른 방법은 렌더링을 하기 전에

      let classes = “container ” + styles.foo;
      이런식으로 변수를 만들어서 하는방법도 있습니다.

      • Changsoo Yoon

        도움이 되었습니다 ^^ 감사합니다.

  • Yoon Jae Park

    설정 하는법 문의 드립니다!! data-grid 모듈을 npm으로 설치하여 쓰려고하는데 node_module에 있는 css를 못불러오는데 webpack에서 설정해야 될꺼같은데 어떤식으로 해야되나 질문들려요!!

    • loader: ‘style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]’
      이렇게 되어있던걸, 그냥 이렇게 해보세요.
      loader: ‘style!css-loader’

      그리고 data-grid 모듈의 경우엔 js 파일에서 import 하셔도 되구, 아니면 webpack config 의 entry 부분에 배열 형태로 index.js 전에 불러오시면 되겠습니다.

  • Sung Jun Wi

    React-hot-loader v3 https://gist.github.com/velopert/c5b1f5f748d9aa8b78f729a321682230
    이거랑 같이 사용할려면 이런식으로 해줘야하네요.

    – module.hot.accept(‘./components/App’, () => {
    – const NextApp = require(‘./components/App’).default;
    + module.hot.accept(‘./components’, () => {
    + const NextApp = require(‘./components’).App;

    근데 모든 모듈과 react 버전이 달라서 그런가… className={ } 에 style import 한거 쓰는데 안되네요.
    className=’ ‘ 이거는 되고요.
    loader를 ExtractTextPlugin.extract(‘css’) 써서 그런가 해서
    loader: ‘style!css’ 로 바꿔서 해봤는데도 안되네요.

  • dali high

    감사합니다.
    file-loader는 public(또는 지정) 디렉터리에 저장해놓고 경로를 참조하는 것으로 알고 있는데,
    url-loader는 바이너리를 base64 스트링 형태로 바꾼다고 하는데요. 예를 들어 이미지파일을 정말 문자열 형태로 표현한다는 말인가요? 마치 윈도 메모장에서 png파일을 열었을 때의 그 외계어 형태로…? 메모장과의 포맷은 다르겠지만

  • 배정모

    {
    test: /.css$/,
    loader: ‘style!css-loader?modules…….:base64:5]’
    }

    이 구문에서 에러가 많이 나는데 이 방법이 가장 깔끔한거 같아서 올립니다.
    {
    test: /.css$/,
    use: [
    ‘style-loader’,
    {
    loader: ‘css-loader’,
    options: {
    modules: true,
    importLoaders: 1,
    localIdentName: ‘[name]__[local]___[hash:base64:5]’
    }
    }
    ]
    }