React에 SCSS 적용및 기본 사용법(1)

React, 혹은 다양한 Framework로 프로젝트를 진행하다보면 Front-End개발자는 css작업을 하게 된다. css는 추가적인 플러그인을 설치할 필요 없이 사용할 수 있고, 사용 환경에 영향을 받지 않기 때문에 많은 사람이 css을 사용한다.

하지만 프로젝트가 복잡해지다보면 이 css파일이 같은 내용이 많아지고, 그 양이 방대해지게 된다. 이를 해결하기 위해 등장한 것이 css 전처리기(css Preprocessor)이다. css 전처리기는 이름 그대로 css가 동작하기 전 동작하는 예비 처리기로서

- 중첩 구문 해결
- 변수 정의 기능
-  mixins 을 정의하는 기능
- 수학 함수 처리 기능 등...

등의 특징을 지니며, css의 태생적 한계를 해결해 준다. css 전처리기의 종류로는

가 있다. 모두 고유의 장점과 고유의 특징이 있으면서 비슷한 특징들(mixin 등)이 있으니, 프로젝트 진행시 편한 전처리기를 선택하면 된다.

Sass/Scss

2018 기준 Sass/Less/Stylus

개인적으로는 가장 오래된 CSS Preprocessor 이자 가장 큰 커뮤니티를 가지고 있기 때문에 Sass를 공부하였다. Sass(Syntactically Awesome Style Sheet)은 css3 의 확장으로서 Dart 기반으로 작동하며, Sass와 Scss 두개의 문법을 제공한다.

Sass가 처음 등장하였을 때 문제시 되었던 것은 기존 css와 너무나 다른 문법이였다. 때문에 점차적으로 많은 개선이 이루어졌고, 3.0 버전 이후에 Scss문법이 등장하였다.

이번 게시물에서는 Scss 기준으로 내용을 작성하도록 하겠다.

React에 Scss 적용

위 게시물에 create-react-app에 관해서 간략하게 서술하였으니 참조 바란다.

우선 Create-React-App을 통해 React 프로젝트를 생성하겠다.

- create-react-app scss_test
- cd scss_test
- yarn start

처음 프로젝트를 만든 뒤, src폴더에 들어가서 App.css의 이름을 App.scss로 변경해보자. 그다음, App.js에 들어가 css대신 scss을 import한다고 변경해보자.

scss 적용 실패!

보시다시피 css가 완전히 깨진 걸 확인할 수 있다. 이제부터 우리 프로젝트가 제대로 scss를 읽을 수 있게 해보자.

React에서 scss를 사용하기 위해서는 webpack을 수정해야 한다. 하지만, create-react-app에서 project를 만들경우 처음에는 webpack을 수정할 수 없으니, eject 명령을 통해 프로젝트를 customize해야한다.

- cd scss_test
- yarn eject

참고로, GitHub같은 오픈소스 사용경우, 기존 코드를 commit후에야 eject명령어를 사용할 수 있다 그리고 eject이후에는 프로젝트를 eject이전으로 되돌릴 수 없다! eject명령어 이후 프로젝트를 살펴보자.

eject이후 directory 구조

Scss를 적용하기 위해서 우리가 수정해야 할 파일은 webpack.config.dev.jswebpack.config.prod.js이다.

두 개의 파일을 수정하기 전에, 먼저 필요한 두 package를 추가하겠다.

- yarn add node-sass sass-loader

node-sass는 scss를 다를 수 있는 node program이고, sass-loader는 webpack에 필요한 loader이다.

이제, 이를 webpack에 추가시키면 된다. 먼저, webpack.config.js파일을 연다.

css 로더

스크롤을 내리다 보면 css 관련 loader부분들이 있다. 이 부분을 scss를 사용할 수 있도록 수정하면 된다. 160번째 줄 test: /\.css&/를 다음과 같이 수정한다.

test: /\.(css|scss)$/,

그 다음, 170째 줄 postcss-loader밑에 scss를 위한 새로운 loader를 추가하면 된다.

{                
loader: require.resolve("sass-loader"),
options: {
sourceMap: true
}
}

프로젝트를 yarn start로 다시 작동시켜보자.

fix!

이제 작동하게 된다!

scss을 css로 변환하기 위해서는 postcss-loader에도 sourceMap을 적용해야 한다.

sourceMap

이제 scss파일을 css로 변환해서 사용할 수 있다.

App.scss파일에서 변수를 정의해서 사용해보도록 하자.

bg-color

$bg-color라는 변수를 정의한 뒤 text의 색깔을 변경해보자.

color red!

색깔이 정상적으로 변경된다.

Production에 Scss 적용

그렇다면, 우리가 작성한 scss파일을 실제 서버에 올릴때도 정상 작동할까?

다음 명령어를 실행해보자.

- yarn build

우리의 코드를 압축하고, uglify하고, build하여 실제 production(배포)할 때 사용할 코드를 만든다. 새롭게 생긴

build 폴더 -> static -> css 에 들어와서 코드를 확인해보자. 하지만 scss파일의 흔적이 보이지 않는다.

이를 해결하기 위해서는 webpack.config.dev.js파일 대신 webpack.config.prod.js 파일을 수정해야 한다. 이름 그대로 production을 위한 webpack파일이다. webpack.config.dev.js에 scss를 적용했을때와 같이 수정하면 된다.

1. css 부분
2. css -> (css|scss) 로 변경
3. sass-loader 추가
4. postcss-loader에 sourceMap추가

이제 scss파일이 변환, 압축되어 css파일이 된 걸 확인할 수 있다.

Css 모듈

다음과 같은 코드가 있다고 가정해보자.

<Nav /> ==> Nav.scss
<p className="container"
<App /> ==> App.scss
<p className="container"

내가 원하는 건 각각 Component마다 className을 같게 하더라도 다른 style 적용을 원한다. 하지만 회사에서, 혹은 팀별로 프로젝트를 진행하다보면 className은 겹칠 수 밖에 없고, css 충돌이 일어날 수 있다.

이를 해결하기 위해 css 모듈 이 만들어졌다. 즉, css의 충돌을 방지할 수 있게 된다. css 모듈을 적용하면, 위에 코드는 다음과 같이 변경된다.

<Nav /> ==> Nav.scss
<p className="Nav__container__a4sdfae1"
<App /> ==> App.scss
<p className="App__container__ps441121"

container라고 className을 지정하더라도, webpack이 자동으로 위와 같이 Component이름, className이름, 그리고 임의의 숫자의 조합으로 변경해주어 css 충돌을 방지하게 된다.

이를 적용하는 것은 간단하다. 우선, webpack.config.dev.js파일 -> css-loader부분으로 이동한다.

css module

위 사진처럼 options부분에 modules: true 라고 입력하면 된다. 마찬가지로 webpack.config.prod.js파일에도 적용하면 된다. 이제 yarn을 재시작해보자.

break again!

다시 css가 깨진 걸 확인할 수 있다.

css name is break…

browser에서 확인하면 webpack이 이상한 class이름으로 css을 실행하고 있는 걸 확인할 수 있다. webpack이 class이름을 랜덤으로 실행하기 때문이다.

css모듈을 사용하기 위해서는 scss파일을 불러오는 js파일, 그리고 scss파일을 수정해야 한다.

App.js

styles을 사용할 때 ‘-’(대쉬)는 사용 불가능하기 때문에 이를 ‘_’(언더스코어)로 변경해야 한다. scss파일도 언더스코어로 대체하자.

App.scss

Scss 사용해보기

실제로 scss을 사용해보기 위해, 임의의 Component와 scss파일을 생성해보도록 하자.

Footer.js

다른 프로젝트에서 사용했던 Footer Component를 가져와봤다. 이를 위한 scss파일은 어떻게 작성하면 될까?

Footer.scss

기존 css 파일 방식으로 작성을 하였다면

.footer {
~~~~내용 내용,,,,
}
.column {
~~~내용 내용,,,
}
...
...

이렇게 각각의 class별로 작성을 하였을 것이다. 하지만 scss는 Component의 구조 그대로 작성하면 된다.

.footer {
.column {
    .nav {
...내용 내용 ,,,
    }  
}
}

scss파일의 코드를 좀 더 자세히 살펴보자.

2 line: 다른 파일에서 변수를 선언해서 사용하고 있다. 하지만, 지금 작성한 Footer.scss파일에서는 import한 부분이 없다! 이를 어떻게 사용하는 걸까?
12 line: @include breakpoint라는 처음보는 코드가 있다. 이는 mixin을 사용하여 작성된 것이다.

다음 블로그 내용에서는 Footer.scss파일에서 import 없이 변수가 사용된 것, 그리고 mixins 부분에 대해 작성하도록 하겠다.

React에 SCSS 적용및 기본 사용법(2)