[리액트(React) Study Log] [Person App-027] Enabling & Using CSS Modules
1. CSS module 의 기능
- css 파일을 각 component 별로 scoped 되게 해서, 여러 종류의 component 에서 중복되는 class name 을 사용해도 CSS modules 가 background 에서 자동으로 중복되지 않는 class name 을 부여한다.
- CSS Modules allows the scoping of CSS by automatically creating a unique classname of the format [filename]\_[classname]\_\_[hash].
- CSS Modules 를 사용하려면 CRA로 만든 app 을 eject 해서, config 파일에서 위의 기능을 하도록 CSS Modules 환경설정을 해줘야 함.
2. 사전 작업
- Person.js 와 App.js 에서 radium 관련 내용 모두 삭제.
- npm run eject --> config 폴더와 scripts 폴더가 새로 생성됨.
- config 폴더의 webpack.config.js 파일의 내용 중 아래 부분을 찾아서 수정
(react 16.7 버젼 기준)
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
}),
- 아래 내용을 추가
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
- 변경 후
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
}),
3. css modules 사용 방법
- css 파일 import 시 css 파일내 설정을 대표하는 객체 이름으로 import 함.
- 기존
import './App.css';
- 변경 ; 아래와 같이 import 하면 css classes(App, red, bold 등) 를 property 로 갖는 javascript object(classses)가 생성됨. --> className 을 classes.App, classes.red 등으로 지정하면, 해당 css 선택자가 적용됨. 즉 생성된 classes 객체를 통해 css 파일과 js 파일이 연결됨. --> background 에서는 설정시 지정한 [name]__[local]__[hash:base64:5] 형태의 unique 한 className 이 만들어져서 중복을 방지해주므로 여러 component 에서 일반적인 class 이름을 자유롭게 사용할 수 있음. (생성된 class name 은 console 의 html code 에서 확인 가능.)
import classes from './App.css';
- 기존에 사용하던 변수인 classes 는 name 충돌을 방지하기 위해 assignedClasses 로 모두 변경함. string 으로 되어 있던 class name은 classes.red, classes.bold, classes.App 으로 변경.
// src-App.js
...
let assignedClasses = [];
if (this.state.persons.length <= 2) {
assignedClasses.push( classes.red ); // classes = ['red']
}
if (this.state.persons.length <= 1) {
assignedClasses.push( classes.bold); // classes = ['red', 'bold']
}
return (
<div className={classes.App}>
<h1>Hi, I'm React App</h1>
<p className={assignedClasses.join(' ')}>This is really working!</p>
...
- Person.js 파일도 아래와 같이 작업
//src-Person-Person.js
...
import classes from './Person.css';
const person = (props) => {
return (
<div className={classes.Person}>
...