gulp include 활용기

gulp include를 활용해 재사용 가능한 component 작업을 해봅시다.


들어가며

이번에 진행한 프로젝트 환경을 gulp 환경으로 세팅하였는데, 그동안 gulp를 꽤 오래 4-5년 정도 사용하였지만 이번만큼 gulp 환경을 잘 활용했던 때는 없었던 것 같아서 gulp 환경 제대로 활용할 수 있는 방법을 적어보고자 합니다.



gulp를 왜 사용했을까?


먼저, 제가 gulp 환경으로 작업 환경을 세팅했던 이유는 세 가지입니다.

  1. sass
  2. include
  3. ES6

이 세 가지를 위해 gulp 환경이 필요했는데, 이번 프로젝트에서 특히 잘 활용했던 것은 include였습니다.

그동안은 include를 사용할 때 뭔가 값을 던질 수 있다는 것을 몰라서 단순히 gnb나 head에 들어가는 파일을 import 하는 정도로 사용했었는데, 작년에 다른 프로젝트 서포트 하면서 태용 책임님이 include에 값을 던지는 것을 보고 느낌표가!! 딱! 우와 이걸 이렇게도 쓰는구나 싶어서 이번 프로젝트에서는 include를 component처럼 사용하려고 했습니다.

gulp include를 사용할 때 선언 방식은 gulpfile.babel.js 파일에서 설정할 수 있는 데 저는 prefix 와 suffix를 주석 형태로 사용했으니, 참고 부탁드립니다.

prefix: "<!--",
suffix: "-->",

include 기본 형태

<!-- include('../include/head.html') -->

head.html 파일 내용

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>xegroup blog</title>
  </head>
  <body>
    <div class="wrap">

head include page 적용 코드

<!-- include('../include/head.html') -->
      <!-- 본문바로가기 -->
      <div class="skip_nav">
        <button>본문 바로 가기</button>
      </div>
      <main id="container" class="container">
        ...
      </main>

build 결과 코드

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>xegroup blog</title>
  </head>
  <body>
    <div class="wrap">
      <!-- 본문바로가기 -->
      <div class="skip_nav">
        <button>본문 바로 가기</button>
      </div>
      <main id="container" class="container">
        ...
      </main>

include는 위 방식으로 파일을 import 할 수 있습니다. 가장 기본적인 형태이며, 여기서 조금 활용을 한다면 페이지 내에서 include 파일로 값을 던질 수 있습니다.

페이지 개별 class를 값으로 넘겨준 예시

<!-- include('../include/head.html', {
  wrapperClassName: 'sub_wrap'
}) -->

head.html 파일 내용

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>xegroup blog</title>
  </head>
  <body>
    <div class="wrap <!-- wrapperClassName -->">

build 결과 코드

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>xegroup blog</title>
  </head>
  <body>
    <div class="wrap sub_wrap">

include 내에서 if 문 사용하기

include 내에서 if 문도 사용이 가능합니다. 물론 if만 사용 가능해서 else나 if else를 사용할 순 없지만 그래도 if 문을 사용할 수 있는 것만으로도 gulp include의 활용성이 굉장히 높아졌습니다.

아래 예시는 프로젝트마다 굉장히 많이 사용하는 리스트 없음 케이스의 마크업입니다. 보통 공통으로 제작되어 사용하지만, 케이스가 조금씩 달라서 if 문을 사용할 수 없다면 하나의 component로 사용하긴 어려운 경우가 많으나, gulp include에서 if 문을 사용하면 하나의 파일로 관리할 수 있습니다.

nolist.html 작성 예시

nolist.html 파일 내용

<div class="nolist_wrap">
  <div class="nolist_inner">
    <!-- if (title !== '') {
      <div class="nolist_heading"><!-- title --></div>
    } -->
    <div class="nolist_desc"><!-- desc --></div>
  </div>
</div>


nolist include page 적용 코드 1

<!-- include('../include/nolist.html', {
  title: '검색결과가 없습니다.',
  desc: '다른 검색어를 입력해보세요.'
}) -->

build 결과 코드 1

<div class="nolist_wrap">
  <div class="nolist_inner">
    <div class="nolist_heading">검색결과가 없습니다.</div>
    <div class="nolist_desc">다른 검색어를 입력해보세요.</div>
  </div>
</div>

nolist include page 적용 코드 2

<!-- include('../include/nolist.html', {
  title: '',
  desc: '게시물이 없습니다.'
}) -->

build 결과 코드 2

<div class="nolist_wrap">
  <div class="nolist_inner">
    <div class="nolist_desc">다른 검색어를 입력해보세요.</div>
  </div>
</div>

이렇게 두 가지 스타일의 하나의 component로 쉽게 관리할 수 있습니다. display none으로 코드를 지저분하게 만들지 않고 사용할 수 있어 굉장히 유용했어요. 유의할 점은 값이 없을 경우에도 변수는 선언해주되 빈값으로 넘겨야 합니다. 그렇지 않을 경우 gulp build 에러가 생겨요.



include 내에서 for 문 사용하기

if 문뿐만 아니라 for 문도 사용가능합니다. 값을 배열로 넘겨주면 for 문을 이용한 처리도 가능한데요. 저는 head.html을 component로 작업할 때 title 부분을 각 페이지에 맞게 적용할 때 사용했습니다.

head.html 작성 예시

head.html 파일 내용

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>
      <!-- for (var i = navMenu.length - 1; i >= 0; i --) {
        `+ navMenu[i] +` >
      } --> xegroup blog
    </title>
  </head>
  <body>
    <div class="wrap">

head include page 적용 코드

<!-- include('../include/head.html', {
  navMenu : ['기타', 'gulp include 활용 어디까지 해봤니?'],
}) -->

build 결과 코드

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>gulp include 활용 어디까지 해봤니? > 기타 > xegroup blog</title>
  </head>
  <body>
    <div class="wrap">

예시 코드에서 한 가지 유의할 점은 for 문을 배열의 역순으로 작업했다는 거예요. 이유는 다음 예시를 보면서 설명드릴게요~



include를 중첩해서 사용도 가능

include 파일 내에 include를 포함할 수 있어요. 이때 변수도 내부에 있는 include로 전달 가능합니다. (작업하다 보면 vue 환경에서 작업할 때 props 지옥에 빠진 것과 동일한 기분을 느끼게 됩니다.. ㅋㅋㅋ)

예시 코드는 페이지 내 title과 페이지 내부에 있는 경로 표시를 한 번만 선언하고 활용할 수 없을까 하는 고민에서 시작되어 만들어진 코드입니다.

head.html, root.html 작성 예시

head include page 적용 코드

<!-- include('../include/head.html', {
  navMenu : ['기타', 'gulp include 활용 어디까지 해봤니?'],
}) -->

head.html 파일 내용

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>
      <!-- include('../include/root.html', {
        type: 'title',
        navMenu : <!-- navMenu -->,
      }) -->
    </title>
  </head>
  <body>
    <div class="wrap">
      <main id="container" class="container">
        <!-- include('../include/root.html', {
          type: 'nav',
          navMenu : <!-- navMenu -->,
        }) -->
      </main>

root.html 파일 내용

<!-- if (type == 'title') {
  <!-- for (var i = navMenu.length - 1; i >= 0; i --) {
    `+ navMenu[i] +` >
  } --> xegroup blog
} -->
<!-- if (type == 'nav') {
  <div class="page_nav">
    <a href="#">
      <i class="ico ico_home ico_xs"></i>
      <span>HOME</span>
    </a>
    <!-- for (var i = 0; i < navMenu.length; i ++) {
      <a href="#">
        <span>`+ navMenu[i] +`</span>
      </a>
    } -->
  </div>
} -->

build 결과 코드

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>gulp include 활용 어디까지 해봤니? > 기타 > xegroup blog</title>
  </head>
  <body>
    <div class="wrap">
      <main id="container" class="container">
        <div class="page_nav">
          <a href="#">
            <i class="ico ico_home ico_xs"></i>
            <span>HOME</span>
          </a>
          <a href="#">
            <span>기타</span>
          </a>
          <a href="#">
            <span>gulp include 활용 어디까지 해봤니?</span>
          </a>
        </div>
      </main>

값 자체는 동일하나 title은 웹 접근성 관점에서 역순으로 나오는 게 맞는 거 같아서 title의 for 문은 역순으로 나오게 작업되었고, 페이지 경로를 표시해 주는 부분은 바르게 나오게 작업 되었습니다. 이렇게 작업되면 경로가 수정될 때 head.html만 수정하면 title과 페이지 내 경로 부분도 같이 수정되기 때문에 수정 공수를 줄일 수 있습니다.

한 번 이상 재사용되는 코드들을 이런 식으로 include로 관리하다 보면 프레임워크에서 component로 관리할 때만큼 작업 시간을 단축할 수 있는 거 같아요.

마치며

지난 프로젝트에서 gulp include를 이런 식으로 활용해서 팔로업때 수정 공수를 많이 줄일 수 있었답니다. 여러분도 프레임워크 환경이 아닌 일반 html 환경에서 화면 작업을 해야 할 때 단순 반복 작업이 걱정이 된다면, gulp 환경으로 세팅해서 include를 적극 활용해 보는 건 어떨지 고민해 보아요!


추천 글