[React] CSS Module

๊ฒจ๋ ˆยท2024๋…„ 11์›” 18์ผ

[React] ๋ฆฌ์•กํŠธ ์Šคํ„ฐ๋””

๋ชฉ๋ก ๋ณด๊ธฐ
51/95

๐Ÿ“ CSS Module
CSS๋ฅผ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•  ๋•Œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ๊ณ ์œ ํ•œ ๊ฐ’, ์ฆ‰ [ํŒŒ์ผ ์ด๋ฆ„]_[ํด๋ž˜์Šค ์ด๋ฆ„]__[ํ•ด์‹œ๊ฐ’] ํ˜•ํƒœ๋กœ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์„œ ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ ํด๋ž˜์Šค ์ด๋ฆ„์ด ์ค‘์ฒฉ๋˜๋Š” ํ˜„์ƒ์„ ๋ฐฉ์ง€ํ•ด ์ฃผ๋Š” ๊ธฐ์ˆ 

โ“๐Ÿค” CSS Module์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด?
๐Ÿ‘‰ css-loader ์„ค์ •์„ ๋ณ„๋„๋กœ ํ•ด์•ผ ํ–ˆ์ง€๋งŒ, v2 ๋ฒ„์ „ ์ด์ƒ๋ถ€ํ„ฐ๋Š” ๋”ฐ๋กœ ์„ค์ •ํ•  ํ•„์š” ์—†์ด .module.css ํ™•์žฅ์ž๋กœ ํŒŒ์ผ์„ ์ €์žฅํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด CSS Module์ด ์ ์šฉ๋œ๋‹ค.


  • ์˜ˆ์ œ
    • SSModule.module.css
      /* ์ž๋™์œผ๋กœ ๊ณ ์œ ํ•ด์งˆ ๊ฒƒ์ด๋ฏ€๋กœ ํ”ํžˆ ์‚ฌ์šฉ๋˜๋Š” ๋‹จ์–ด๋ฅผ ํด๋ž˜์Šค ์ด๋ฆ„์œผ๋กœ ๋งˆ์Œ๋Œ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ */
      .wrapper {
       background: black;
       padding: 1rem;
       color: white;
       font-size: 2rem;
      }
      
      /* ๊ธ€๋กœ๋ฒŒ CSS๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด */
      :global .something {
       font-weight: 800;
       color: aqua;
      }

CSS Module์„ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ง€์„ ๋•Œ ๊ณ ์œ ์„ฑ์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ํ”ํžˆ ์‚ฌ์šฉํ•˜๋Š” ๋‹จ์–ด๋กœ ์ด๋ฆ„์„ ์ง€์–ด๋„ ๋ฌธ์ œ๋˜์ง€ ์•Š๋Š”๋‹ค. ํ•ด๋‹น ํด๋ž˜์Šค๋Š” ๋ฐฉ๊ธˆ ๋งŒ๋“  ์Šคํƒ€์ผ์„ ์ง์ ‘ ๋ถˆ๋Ÿฌ์˜จ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ๋งŒ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ!

๋งŒ์•ฝ ํŠน์ • ํด๋ž˜์Šค๊ฐ€ ์›น ํŽ˜์ด์ง€์—์„œ ์ „์—ญ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด :global์„ ์•ž์— ์ž…๋ ฅํ•˜์—ฌ ๊ธ€๋กœ๋ฒŒ CSS์ž„์„ ๋ช…์‹œํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.


  • CSS Module์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ์˜ˆ์‹œ
    • SSModule.js
      import styles from './CSSModule.module.css';
      const CSSModule = () => {
       return (
         <div className={styles.wrapper}>
           ์•ˆ๋…•ํ•˜์„ธ์š”, ์ €๋Š” <span className="something">CSS Module!</span>
         </div>
       );
      };
      export default CSSModule;

CSS Module์ด ์ ์šฉ๋œ ์Šคํƒ€์ผ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜ค๋ฉด ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜ ์ „๋‹ฌ๋ฐ›๊ฒŒ ๋˜๋Š”๋ฐ CSS Module์—์„œ ์‚ฌ์šฉํ•œ ํด๋ž˜์Šค ์ด๋ฆ„๊ณผ ํ•ด๋‹น ์ด๋ฆ„์„ ๊ณ ์œ ํ™”ํ•œ ๊ฐ’์ด ํ‚ค-๊ฐ’ ํ˜•ํƒœ๋กœ ๋“ค์–ด ์žˆ๋‹ค.

// ์˜ˆ: ์œ„ ์ฝ”๋“œ์—์„œ console.log(styles)๋ฅผ ํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚จ.
{ wrapper: "CSSModule_wrapper__1SbdQ" }

์šฐ๋ฆฌ๊ฐ€ ์ง€์ •ํ•œ ํด๋ž˜์Šค ์ด๋ฆ„ ์•ž๋’ค๋กœ ํŒŒ์ผ ์ด๋ฆ„๊ณผ ํ•ด์‹œ๊ฐ’์ด ๋ถ™์Œ.

์ด ๊ณ ์œ ํ•œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํด๋ž˜์Šค๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์€ JSX ์—˜๋ฆฌ๋จผํŠธ์— className= {styles.[ํด๋ž˜์Šค ์ด๋ฆ„]} ํ˜•ํƒœ๋กœ ์ „๋‹ฌํ•ด ์ฃผ๋ฉด ๋œ๋‹ค. :global์„ ์‚ฌ์šฉํ•˜์—ฌ ์ „์—ญ์ ์œผ๋กœ ์„ ์–ธํ•œ ํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ ํ‰์ƒ์‹œ ํ•ด ์™”๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ๊ทธ๋ƒฅ ๋ฌธ์ž์—ด๋กœ ๋„ฃ์–ด์ค€๋‹ค.


CSSModule ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ์™€ ์Šคํƒ€์ผ์„ ๋ชจ๋‘ ์ž‘์„ฑํ–ˆ๋‹ค๋ฉด App ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ Œ๋”๋งํ•ด๋ณด์ž.

//  App.js
import React, { Component } from 'react';
import CSSModule from './CSSModule';
 
class App extends Component {
  render() {
    return (
      <div>
        <CSSModule />
      </div>
    );
  }
}
 
export default App;


  • CSS Module์„ ์‚ฌ์šฉํ•œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ๋‘ ๊ฐœ ์ด์ƒ ์ ์šฉํ•  ๋•Œ
    • CSSModule.module.css
      /* ์ž๋™์œผ๋กœ ๊ณ ์œ ํ•ด์งˆ ๊ฒƒ์ด๋ฏ€๋กœ ํ”ํžˆ ์‚ฌ์šฉ๋˜๋Š” ๋‹จ์–ด๋ฅผ ํด๋ž˜์Šค ์ด๋ฆ„์œผ๋กœ ๋งˆ์Œ๋Œ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ */
      
      .wrapper {
       background: black;
       padding: 1rem;
       color: white;
       font-size: 2rem;
      }
      
      .inverted {
       color: black;
       background: white;
       border: 1px solid black;
      }
      
      /* ๊ธ€๋กœ๋ฒŒ CSS๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด */
      
      :global .something {
       font-weight: 800;
       color: aqua;
      }

    • CSSModule.jsx
      import styles from './CSSModule.module.css';
      
      const CSSModule = () => {
      return (
        <div className={`${styles.wrapper} ${styles.inverted}`}>
          ์•ˆ๋…•ํ•˜์„ธ์š”, ์ €๋Š” <span className="something">CSS Module!</span>
        </div>
      );
      };
      
      export default CSSModule;

์œ„ ์ฝ”๋“œ์—์„œ๋Š” ES6 ๋ฌธ๋ฒ• ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด(Template Literal)์„ ์‚ฌ์šฉํ•ด ๋ฌธ์ž์—ด์„ ํ•ฉํ•ด ์คฌ๋‹ค. ์ด ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ž์—ด ์•ˆ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์‰ฝ๊ฒŒ ๋„ฃ์–ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

const name = '๋ฆฌ์•กํŠธ';
// const message = '์ œ ์ด๋ฆ„์€ ' + name + '์ž…๋‹ˆ๋‹ค.'
const message = `์ œ ์ด๋ฆ„์€ ${name}์ž…๋‹ˆ๋‹ค.`;

์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฌธ์ž๋Š” ๋ฐฑํ‹ฑ(Backtick)์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ณ , ํ‚ค๋ณด๋“œ์—์„œ ์ˆซ์žํ‚ค 1 ์™ผ์ชฝ์— ์žˆ๋Š” 'ํ‚ค์ด๋‹ค.

CSS Module ํด๋ž˜์Šค๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์‚ฌ์šฉํ•  ๋•Œ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

className={[styles.wrapper, styles.inverted].join(' ')}
profile
ํ˜ธ๋–ก ์‹ ๋ฌธ์ง€์—์„œ ๊ฐœ๋ฐœ์ž๋กœ ํ™˜์ƒ

0๊ฐœ์˜ ๋Œ“๊ธ€