npm 빌드시 CSS 우선순위가 Local 환경과 달라지는 이유 (feat.Vuetify...)

두별·2022년 11월 21일
9

TIL

목록 보기
30/46
post-thumbnail

현재 진행중인 프로젝트에서는 Vuetify를 사용하고 있는데, Vuetify 컴포넌트의 디자인을 그대로 사용하기에는 한계가 있으므로 퍼블리싱 작업 단계에서 Vuetify 컴포넌트의 Style을 재정의해야 하는 경우가 다분하게 있다.

그런데 Local환경에서는 CSS가 의도한대로 잘 입혀졌으나, npm run build만 하면 Vuetify의 CSS 우선순위가 더 강력하게 먹어서 퍼블리셔를 열받게 하는 것이였다..

이 문제를 해결하지 않으면 퍼블리셔가 CSS를 작성할 때마다 선택자를 아~~~주 길게 써야하고, 일일히 !important를 붙여줘야하는 불편을 겪는다. 나도 개발자가 되기 전에는 퍼블리셔였기 때문에 그 고통을 이해했고, 어떻게든 이 문제를 해결하고 싶었다.

그리고 구글링 했을 때 이 문제에 대한 레퍼런스 또한 별로 없었기 때문에, 같은 문제를 겪는 사람들에게 이 포스팅이 조금이나마 도움이 되길 바란다..

ISSUE : 빌드시 CSS 우선순위가 Local 환경과 다르게 적용됨

재정의한 scss보다 Vuetify의 우선순위가 높게 적용되는 문제

원인 : 모듈화된 CSS를 번들링하는 과정에서 Local과 Dev가 파일을 구성하는 방식에 차이가 있어 우선순위가 다르게 작용됨

현재 프로젝트는 아래와 같이 SCSS를 모듈화한 구조이다. (@import 해서 사용하는 방식)

build 했을 때 우선순위가 달라지는 현상은 이 모듈화된 CSS를 번들링하는 과정에서 발생하게 되는데, Local과 Dev가 번들을 구성하는 방식에 차이가 있어 우선순위가 다르게 적용이 되고 있었다.

웹팩 빌드를 하게 되면 @import한 파일들을 하나의 번들로 묶게 되는데 이 때 하나의 번들에 몰려있으면 초기 애플리케이션 로드 속도가 느려질 수 있기 때문에 번들을 여러개로 분리하여 개선할 수 있는 코드 스플리팅이라는 웹팩 기능이 존재한다.

SCSS도 마찬가지로 컴파일을 거쳐 하나의 CSS로 만들어질 때 코드 스플리팅에 의해 여러개의 CSS 파일로 쪼개지게 되는 것 같다.

Local 우선순위

컴포넌트 내부 CSS > 직접 정의한 SCSS > vuetify 기본 CSS

Dev (build 했을때) 우선순위

컴포넌트 내부 CSS + vuetify 기본 CSS(2) > 직접 정의한 SCSS > vuetify 기본 CSS(1)

여기서 Vuetify가 Local과 Dev 환경에서 번들을 구성하는 방식에 차이가 있음을 알 수 있다. Local에서 vuetify 기본 CSS는 하나로 묶여있었으나 Dev 환경은 속도를 위해서인지? 여러개의 chunk-hash.css로 분리되고 있고 분리된 CSS들이 가장 마지막에 임베드 되어 우선순위를 강력하게 먹고 있던 것이였다.

해결방법

Vuetify를 재정의하는 CSS는 모듈화 하지 않고 index.html에 직접 임베드
가장 우선순위가 강력해야하는 CSS는 모듈화하지 않고 index.html 가장 최하단에 위치할 수 있도록 body 태그 안에 임베드하도록 한다.

SCSS를 사용하고 있는 경우

  1. 브라우저는 SCSS를 모르기 때문에 SCSS를 사용하고 있었다면 SCSS를 CSS로 컴파일한 뒤 index.html에 임베드 해주어야 한다.

    또한 이 과정을 build시에 자동화 되도록 해주는 처리가 필요하다.
  • package.json에 다음과 같이 셋팅
"scripts": {
  "serve": "vue-cli-service serve",
  "build": "npx sass ./src/scss/_main.scss ./public/css/main.css && vue-cli-service build",
  "lint": "vue-cli-service lint"
},
  1. Local에서는 SCSS를 실시간으로 수정하고 결과를 봐야하기 때문에 매번 CSS로 컴파일 하기에는 무리가 있다. 따라서 SCSS를 모듈화한 기존 방법을 유지하되 Dev 환경에서만 Index.html에 CSS가 임베드 되도록 해줘야 한다.

(이미지에 오타있네요) local 환경일때만 x dev/prod 환경일때 o !

  • root 폴더에 .env.production 파일 생성
VUE_APP_CSS_PATH = './css/main.css'
  • index.html
    npm run build 했을때 사용되는 환경변수 적용
<body>
	<link rel="stylesheet" href="<%= process.env.VUE_APP_CSS_PATH %>" type="text/css">
</body>


적용 후 효과는 굉장했다..!

퍼블리셔분께서 뜨거운 반응을 보여주시며 기술 블로그에 꼭 올리라고 하셨다. ㅋㅋㅋㅋㅋㅋㅋㅋ 가이드로 올린 글에도 이렇게 댓글로 좋은 반응 보여주셔서 너무 뿌듯했다. 개발자는 퍼블리셔에게 무조건 안된다고 하기 금지. 개발자도 마음이 편안하고 퍼블리셔도 작업하기 편한 일터를 만들자 !

7개의 댓글

comment-user-thumbnail
2022년 11월 21일

우와~ 저였으면 이런거 고치기 귀찮아서 퍼블리셔한테 떠넘겼을텐데, 대단해요!

1개의 답글
comment-user-thumbnail
2022년 11월 23일

고생하셨습니다! 공유 감사해요 :>

답글 달기
comment-user-thumbnail
2023년 3월 21일

안녕하세요 혹시 동일한 문제로 해결을 못하고 있는데 질문 드려도 괜찮을까요?
업무중에 막힌게 있는데 급한대로 댓글로 남깁니다ㅜㅜ!

2개의 답글