본문 바로가기
개발공부일지/React

React - StyledComponent / CSS-Loader

by Hynn1429 2023. 3. 15.
반응형

안녕하세요.

Hynn 입니다.

 

이번 포스팅에서는 React 에서 StyledComponents , CSS-Loader 를 사용하여 Component 에 CSS를 적용하는 방법을 알아보도록 하겠습니다.

기존의 HTML/CSS 를 학습하신분들이라면, 어떠한 방식으로 문법을 작성하는지만 익히셔도 도움이 될 거라고 생각합니다.

 

===========

===========

 

 

먼저 두가지의 차이점을 이해해야 코드의 상황에 맞는 CSS 적용이 가능합니다.

이 두개의 동작방식은 다르게 동작되므로, 그에 맞는 사용법이 필요합니다.

 

Styled-Components 와 CSS-Loader 는 CSS를 적용하는 결과물은 같지만, 어떻게 적용하는지에 대한 과정이 다른 기능입니다.

각각의 기능에 대한 차이를 이해한다면, 어떻게 적용하는지에 대해서도 쉽게 결과물을 유추할 수 있습니다.

각각의 설정 및 정의를 알아보고, 차이에 맞게 적용을 해보도록 하겠습니다.

 

 

CSS Loader 는 Webpack 의 loader 의 기능으로 사용해야 합니다.

이 기능의 경우, 기존의 JavaScript, JSX, HTML, CSS 형태로 파일이 다 나뉘어 작성하는 방식은 동일합니다.

하지만 HTML 에서 Header 에 Link 를 사용하지 않고, 다른 방식으로 CSS 를 추가하고, 이러한 설정을 webpack 에 반영함으로서 적용이 완료됩니다.

 

이제 사용법을 간단하게 알아보도록 하겠습니다.

먼저 css-loader 를 적용하기 위해서 로더를 npm 을 사용하여 설치해야 합니다. 

여기서 선택지가 두개가 있습니다. 

이를 두가지로 살펴보도록 하겠습니다.

 

먼저 예제를 위해 활용할 로더와 플러그인을 설치하도록 하겠습니다.

아래의 명령어를 사용해야 합니다.

 

npm install css-loader style-loader MiniCssExtractPlugin

여기서 실제 사용은 css-loader 와 style-loader, 혹은 MiniCssExtractPlugin 을 사용할 예정입니다.

이 두개는 목적은 Webpack 에 모듈번들러를 처리하기 위함이지만, 결과물이 다르게 출력됩니다.

 

Webpack 에서 활용될 때 , Style-loader 는 CSS 파일을 통합합니다. 

기존에 작성하는 형태는 HTML, CSS 파일을 나누고, Header 에 <link> Element 를 이용해서 css 파일을 불러오거나, JavaScript 문법에서 "import" 혹은 "require" 와 같은 형태로 가져오는 문법을 사용하여 HTML 과 CSS 를 연결했을 겁니다.

 

이때 Style-loader 는 모듈번들러를 처리하는 과정에서 HTML 파일에 <Style> 을 사용하여 코드를 HTML 파일에 통합하는 형태로 처리합니다.

 

반면에 MiniCssExtractPlugin 은 css 파일을 분리한 형태로 처리하는 것의 차이가 있습니다.

따라서, webpack.config 설정시 이 두개의 로더설정은 조금 다른 형태로 처리가 됩니다.

 

각각의 예제를 살펴보도록 하겠습니다.

 

1) style-loader

  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },

Style Loader 의 경우, 파일이 통합되므로, test 에 파일 확장자에 대한 정보, use 에 사용할 로더의 정보를 입력하는 것으로 완료가 됩니다.

 

2) MiniCssExtractPlugin

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
    ],
  },
  plugins: [
        new MiniCssExtractPlugin({ filename: "index.css" }),
        ]

로더의 기능도 있지만, Plugin 내의 로더가 있는 형태이므로, 변수로 선언을 하여 가져와야 합니다.

그리고 난 뒤 로더를 처리하는 module 내에는 .loader로 작성한 뒤에 Plugin 에서 한번 더 처리를 해야 합니다.

filename 에는 생성될 파일명을 작성합니다. 

 

이렇게 하면 작성이 완료됩니다.

 

 

먼저 Styled Components 는 React 에서 가장 중요한 개념 중 하나인 Components 에 직접적으로 적용하는 CSS 입니다.

즉 , Components 별로 CSS를 설정하고, ".JSX" 에 직접 코드를 작성함으로서, 1개의 Components 를 하나의 JSX 파일로 관리하는 개념입니다.

 

먼저 예시를 작성해서 각코드 별 해석을 살펴보도록 하겠습니다.

 

import styled from 'styled-components'

const Button = styled.button`
  background-color: ${props => props.primary ? 'blue' : 'white'};
  color: ${props => props.primary ? 'white' : 'blue'};
  border: 2px solid blue;
  font-size: 1em;
  padding: 0.5em 1em;
  border-radius: 3px;
`

const App = () => {
  return (
    <>
      <Button primary>Primary Button</Button>
      <Button>Secondary Button</Button>
    </>
  )
}
  background-color: ${props => props.primary ? 'blue' : 'white'};
  color: ${props => props.primary ? 'white' : 'blue'};

이후의 작성은 모두 ES6 문법을 예제로 작성할 예정이며, 위 코드를 각각의 해석을 이용해 사용해보도록 하겠습니다.

먼저 Import 문을 사용하여 Styled 라는 이름으로 Styled-Components 가져오도록 하겠습니다.

일반적으로 JSX 에서 HTML Element 는 소문자로 작성을 했습니다. 일반적이라면 위의 예시에서도 "Button" 이 아니라 "button" 으로 작성을 해야 했지만, 여기서는 "Button" 으로 작성했습니다.

 

문법의 구성을 본다면, 먼저 "Button" 이라는 변수를 지정합니다. 여기서 "Button"은 하나의 Component 로 취급합니다. 즉 Button 이라는 Component 가 생성됩니다. 이 Component 는 React나 HTML 에서 생성한 Component 가 아니라 "Styled-Component" 에서 생성한 Component 입니다. 그리고 Button 이라는 Component 내에는 styled.button 이라는 method를 사용하고 있습니다.

 

여기서 styled 는 "Styled-Component" 를 뜻하고, button 이 우리가 기존에 사용하던 HTML 요소인 "button" 을 뜻합니다.

그리고 백틱 ( ``) 을 사용하여 백틱 내에 어떠한 CSS 를 부여할지를 지정할 수 있습니다.  

하지만 여기서는 JSX 의 문법을 활용하여, 조건부를 사용하여 CSS 부여도 가능합니다.

아래의 예시를 먼저 살펴보도록 하겠습니다.

 

  background-color: ${props => props.primary ? 'blue' : 'white'};
  color: ${props => props.primary ? 'white' : 'blue'}

 

일반적인 CSS 외에도 Styled Components 의 특징은, 위와 같이 JSX 문법으로 조건에 맞게 설정도 가능합니다.

위의 작성 예시는 현재 Button Component 에는 Primary 라는 Props 가 존재합니다. 이를 삼항연산자로 설정하여 true 일 경우에는 파란색을, false 일 경우에는 화이트를 출력하도록 설정이 되어 있습니다. 컬러 역시도 마찬가지입니다. 각각 true, false 일 경우에 알맞는 색상을 지정하여 적용이 가능합니다.

 

전역 스타일 설정도 가능합니다.  이는 조금 다르게 설정을 해야 합니다.  예시 코드와 함께 살펴 보도록 하겠습니다.

import { createGlobalStyle } from 'styled-components'

const GlobalStyle = createGlobalStyle`
  body {
    font-family: 'Helvetica Neue', sans-serif;
    font-size: 16px;
    color: #333;
    background-color: #f9f9f9;
  }

  a {
    color: blue;
    text-decoration: none;
  }
`

const App = () => {
  return (
    <>
      <GlobalStyle />
		< Component />
    </>
  )
}

위의 코드를 살펴보면, 가장 최상단의 Component 가 위치한 JSX 파일에서 Styled-Components 내의 Method 중 "createGlobalStyle" 이라는 메서드를 정의하여 스타일을 적용해야 합니다. 기존의 Styled-Components 와 같이 "styled.element" 형태가 아니라 "createGlobalStyle" 이라는 메서드를 호출 후 백틱으로 동일하게 CSS 를 적용할 수 있습니다.

 

또한 기존의 CSS 에서 ":Hover", ":last-child"와 같은 조건부 설정이나, 애니메이션 설정도 조금 다르게 작성해야 합니다.

역시나 예제코드와 함께 살펴보도록 하겠습니다.

 

import styled, { keyframes } from 'styled-components'

const fadeIn = keyframes`
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
`

const Box = styled.div`
  width: 100px;
  height: 100px;
  background-color: blue;
  opacity: 0;
  animation: ${fadeIn} 1s ease-in-out forwards;
`;

const App = () => {
  return (
    <Box>Hello World</Box>
  )
}

먼저 애니메이션입니다. 일반적으로 애니메이션은 "Styled-Components" 에서 'Keyframes" 메서드를 사용해야 합니다.

이를 import 문에서 역시 가져오도록 선언한 뒤, 위 예제에서는 fadeIn 이라는 변수에 keyframes 메서드에 백틱을 사용하여 애니메이션에 대한 CSS 를 정의합니다.

 

그리고 나서, 실제 styled.element 내에 animation 이라는 명칭 내에 ${변수명} 을 사용하여 Style 을 추가할 수 있습니다.

위 방법은 다른 방법으로도 활용이 가능합니다.

 

바로 위와 같은 keyframes 설정과 유사하게  "css" 메서드를 활용하여, 여러개의 컴포넌트가 정의된 JSX 에서 공통으로 사용할 CSS 를 지정할 수도 있습니다.

아래와 같이 설정하는 예제를 살펴보겠습니다.

import styled, { css } from 'styled-components'

const flexDisplay = css`
	display:flex;
    justify-content : center;
    align-itmes : center;
`

const Box = styled.div`
  ${flexDisplay}
  width: 100px;
  height: 100px;
  background-color: blue;
  opacity: 0;
`

const App = () => {
  return (
    <Box>Hello World</Box>
  )
}

 

위와 같이 설정하면, CSS 메서드만을 사용하여 순수한 CSS 를 정의하여, ${} 를 사용하여 CSS를 적용할 수도 있습니다.

이렇게하면, 자주 사용하는 CSS 는 위와 같이 정의하여, 손쉽게 가져올 수도 있습니다. 

 

또한 :hover, :last-child 와 같은 CSS에서의 가상 클래스를 적용하려면, & 연산자를 이용해 작성해야 합니다.

예시 코드의 예제를 먼저 살펴보도록 하겠습니다.

 

import styled from 'styled-components'

const List = styled.ul`
  list-style: none;
  padding: 0;

  li {
    margin-bottom: 8px;
    padding: 8px;
    background-color: lightgray;

    &:hover {
      background-color: gray;
      color: white;
    }

    &:last-child {
      margin-bottom: 0;
    }
  }
`

const App = () => {
  return (
    <List>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </List>
  )
}

위 예시를 보면 List Component는 Styled.ul 이라는 element 를 사용하고, ul 안의 자식 요소인 li 에 CSS 속성을 부여할 뿐 아니라, & 연산자를 사용하여 2가지의 속성을 부여했습니다.

여기서 & 연산자는 부모요소를 참조하도록 하는 정의이며, & li 는 부모 기존의 li가 부모요소가 되고, 가상 CSS 클래스로서, hover 시, last-child 가상 클래스 를 적용하여, CSS 를 부여하였습니다. 

 

---------------------------

 

일반적으로 Styled Component 의 경우 React 를 사용하여 새롭게 작성을 할 경우에 하나의 컴포넌트에 개별적으로 부여함에 따라, 보다 깔끔하고 체계화된 작성이 가능하기 때문에, 새로운 작성에서 좋습니다.

 

하지만 기존의 코드를 사용해야 할 경우도 존재하기 때문에, 그러한 경우에는 CSS-Loader 와 같은 옵션도 시간을 절약하는 좋은 사용이기때문에, 용도에 맞춰 사용한다면 좋은 결과를 가질 수 있을 거라고 생각됩니다.

 

다음 포스팅에서는 CRA 에 대해서 다루어보도록 하겠습니다.

 

감사합니다.

반응형

댓글