Skip to content

Latest commit

 

History

History
95 lines (67 loc) · 11.5 KB

templateLoader.md

File metadata and controls

95 lines (67 loc) · 11.5 KB

템플릿 로더 이해하기

로더(loader)란?

  • 웹팩은 기본적으로 자바스크립트로 구성되어 있다. 자바스크립트에서 사용 불가능한 코드는 자바스크립트에서 해석할 수 있는 방식으로 변환하여 처리한다. 웹팩에서 로더(loader)는 자바스크립트 코드 뿐만 아니라 css, scss, html, handlebar, lodash ejs 등의 자바스크립트가 아니거나 자바스크립트 이외의 코드를 포함하는 다양한 포멧의 파일을 자바스크립트로 코드를 해석하여 자바스크립트만 처리할 수 있는 웹팩이 처리할 수 있도록 만든다. 웹팩의 로더는 webpack.config.js에서 config.module.rules 부분에서 설정할 수 있다.
  • 자바스크립트에 다른 형식의 파일을 불러오기 위해서는 require('대상_경로'), import '대상_경로', import 변수 from '대상_경로'의 문법을 사용하여 다른 형식의 파일을 불러 올 수 있다. 이렇게 자바스크립트에서 외부 파일을 불러올 때 웹팩의 로더가 적용된다.

html-webpack-plugin의 기본 템플릿

  • 템플릿이란? 템플릿이란 어떤 것을 만들 때 사용되는 틀을 의미한다. 어떤 특정한 형태를 만들어 두면 여러 번 재사용할 수 있는 것을 템플릿이라고 말한다. html에서 템플릿이란 어떤 형태의 html 문서에 여러 다른 값을 주입하여 다양한 형태로 재사용할 수 있는 형식의 템플릿을 의미한다.
  • 순수한 html은 코정된 형태의 html 구성만을 가지므로 템플릿으로 사용할 수 없다. html을 템플릿으로 사용하기 위해서는 순수한 html이 아닌 재활용할 수 있는 방식의 무언가를 가진 템플릿 기능이 가미된 html을 사용해야 한다.
  • html-webpack-plugin은 기본적으로 lodash ejs 템플릿을 사용한다. lodash ejs 모듈은 html에서 <% %> 사이에 자바스크립트 코드를 사용할 수 있는 기능을 제공한다. 자바스크립트 코드가 만들어낸 문자열이 html의 코드가 되어 빌드를 통해서 순수한 html을 만드는 기능을 한다.
  • html-webpack-plugin은 어떤 구조의 html 파일에서 lodash ejs 템플릿 문법을 사용하여 여러 값을 html에 주입할 수 있다. 이 주입된 값을 이용하여 어떤 형태의 html을 다양한 형태로 재사용할 수 있는 기능을 제공한다.

html-webpack-plugin의 기본 템플릿의 한계

  • html-webpack-plugin의 기본 템플릿은 <%= require('자바스크립트/모듈의/파일/경로.js').함수명()_또는_변수명 %>와 같이 자바스크립트 모듈을 불러올 수 있다.
  • lodash ejs 템플릿은 html 파일에 자바스크립트 코드를 쓰는 것이다. 하지만 외부 파일을 불러오는 것은 자바스크립트 모듈이다. 따라서 html 템플릿을 확장하는 방식으로 코드를 작성할 수는 없고, 자바스크립트를 불러오는 방식으로 코드를 짜야 한다.
  • 홈페이지를 만들다 보면 페이지별로 헤더 푸터 사이드바 등 공통적으로 사용되는 html 태그 구조가 있다. html 별로 이들 태그를 만들다 보면 변경사항이 발생할 때 모든 태그를 다 고쳐야 하는 일이 생긴다. html 태그 조각을 만들어서 불러오는 방식을 사용하면 여러 페이지에서 공통적으로 사용하는 태그 조각을 하나의 파일로 관리할 수 있다.
  • lodash ejs 템플릿에서 html 태그 조각을 불러오는 방식은 자바스크립트 모듈을 불러오는 것이고 이 방식은 모든 태그를 자바스크립트 모듈로만 구성해야 한다는 문제점이 있다. html 코드를 문자열로 짜야하므로 IDE에서 코드의 자동완성이 되지 않는 문제가 있으며 자바스크립트로 짜기 때문에 프로그래밍에 익숙하지 않은 디자이너와 소통을 할 때 또는 초보 개발자들이 어려움을 겪을 수 있다.

사용할 수 있는 템플릿 로더

  • html-webpack-plugin에서 사용할 수 있는 템플릿 엔진은 다음과 같다.
  • pug, ejs, underscore, handlebars, html-loader
  • underscore 템플릿 엔진은 html-webpack-plugin에서 사용할 수 있는 기본 템플릿 엔진인 lodash ejs 템플릿과 동일한 템플릿 엔진이다.
  • html 문법을 간략히 한 문법을 사용하여 코드를 작성할 수 있다. 코드 자동완성 IDE 확장을 제공하기 때문에 편하게 개발 할 수 있다.
  • html 문법을 간략히한 문법으로 작성하기 때문에 pug 문법에 익숙한 개발자는 생산성이 증가되지만, 익숙하지 않은 개발자는 새로운 문법을 익혀야 하고 학습에 시간이 걸린다는 단점이 있다. 또한 디자이너 및 퍼블리셔와 협업할 때 이들이 전혀 코드를 알아볼 수 없기 때문에 개발자 쪽에서 html에 관한 모든 문제를 해결해야 한다.
  • html 문서 내에서 <% %> 문법을 사용하여, 자바스크립트 코드를 쓸 수 있는 문법이다. underscore 템플릿 문법보다 더 다양한 구문을 제공한다.
  • 자바스크립트 코드를 사용하기 때문에 웹 개발자라면 특별한 문법을 추가적으로 익힐 필요 없이 코드를 짤 수 있다는 장점이 있다.
  • 하지만 자바스크립트는 작성자의 수준에 따라 코드의 수준 차이가 많이 날 수 있기 때문에 html 코드에 포함된 자바스크립트를 이해하기 어려운 경우가 생길 수 있다.
  • html 코드와 자바스크립트 코드 모두에 대한 자동완성 기능을 제공하는 IDE 확장 프로그램이 없다는 단점이 있다.
  • 최대한 html의 원형을 그대로 활용하는 템플릿 문법을 갖고 있다. html에 가장 가까운 코드로 구현되어 있기 때문에 디자이너나 퍼블리셔와의 협업을 할 때 코드를 알아보기 쉽다는 장점이 있다.
  • IDE 등의 확장 프로그램을 통해서 코드의 자동완성이 가능하므로 html 및 자바스크립트 코드에 익숙하지 않은 사람들이 사용하기에 좋다.
  • 순수한 html의 코드 조각을 만드는 기능을 가지고 있다. 다른 템플릿 문법과 달리 순수한 html 코드만을 사용할 수 있어서 동일한 html 코드 조각을 반복 사용할 수는 있지만, 동일한 코드 조각을 다양한 형태로 변환하여 사용할 수 없다는 단점이 있다.
  • html-loader 내부의 코드에서 호출하는 로컬 파일 경로는 웹팩이 빌드될 때 해시화 되거나 이미지 파일의 경우 base64 포멧의 코드로 표현되는 특성이 있다.

로더를 불러오는 방법

  • 로더를 사용하는 방법에는 두 가지 방법이 있다. 하나는 webpack.config.jsconfig.module.rules 부분에 사용할 로더를 설정하는 것이며, 또 다른 하나는 importrequire 등의 모듈을 불러오는 부분의 모듈 파일의 경로 앞에 import '경로', import 변수 from '경로', require('경로')가 아닌, import '로더명!경로', import 변수 from '로더명!경로', require('로더명!경로')를 사용하여 외부 파일을 웹팩의 자바스크립트로 불러올 때 로더를 지정하는 방식을 사용할 수 있다.
  • 로더명!경로의 문자열을 사용할 때 !로더명!경로, !!로더명!경로, -!로더명!경로와 같은 접두사를 붙여서 다른 로더의 적용을 제한할 수 있다. 웹팩에서 webpack.config.jsconfig.module.rules에서 설정된 로더는 웹팩 전체에 적용이 된다. 따라서 로더명!경로로 외부 모듈을 불러올 때 지정된 로더 뿐만 아니라 웹팩 전체에 적용되고 있는 로더도 함께 적용된다. 웹팩에 적용된 다른 로더의 적용을 무시하고 로더명!경로로 지정한 로더만 적용되도록 할 때 !, !!, -!와 같은 접두어를 사용할 수 있다.
  • 로더에는 프리로더, 로더, 포스트로더라는 개념이 있다. 웹팩은 자바스크립트를 처리할 수 있으며, 로더는 자바스크립트 코드가 아닌 대상도 모듈로 불러올 수 있도록 하는 기능을 가지고 있다. 이런 비-자바스크립트 모듈을 로더가 불러오기 전에 미리 처리하는 작업을 하는 기능을 프리 로더라고 부르며, 비-자바스크립트 모듈을 로더로 불러온 이후 후처리를 하는 기능을 포스트 로더라고 부른다.
  • ! : 웹팩에 설정된 일반 로더를 비활성화 한다.
  • !! : 웹팩에 설정된 일반 로더 뿐만 아니라 프리 로더와 포스트 로더를 비활성화한다.
  • -! : 웹팩에 설정된 포스트 로더만을 활성화하고 나머지(일반 로더와 프리로더를 비활성화 한다.)
  • 접두어에 관한 설명은 인라인(Inline)을 참고하도록 하자.

모듈 경로에서 여러 로더 사용하기

  • 로더명1!로더명2!로더명3!로더명4!경로와 같은 방식으로 하나의 모듈을 불러올 때 여러개의 로더를 사용할 수도 있다.
  • 'style-loader!css-loader?modules!./styles.css'
  • 접두어는 첫 번째 로더명의 앞에 붙여 준다. !!로더명1!로더명2!로더명3!로더명4!경로와 같은 방식으로 맨 앞에 !!를 추가해 주었다. 접두어를 통해 웹팩 전체에 적용되는 로더의 활성 비활성 설정은 각각의 로더명에 개별적으로 적용되지 않고 함께 적용된다는 것을 알 수 있다.

모듈 경로에서 로더 옵션 사용하기

  • 로더명?옵션!의 형식으로 로더명! 사이에 ?옵션을 넣을 수 있다.
  • 로더의 옵션은 ?key=value&foo=bar와 같은 쿼리 파라메터 형식 또는 ? { "key": "value", "foo": "bar"}과 같은 json 형식을 사용할 수 있다.

템플릿 로더 사용시 주의할 점

  • 로더명!경로의 표현식에서 '로더명!경로'는 문자열으로 이뤄져야 한다. `로더명!${경로_변수}` 또는 '로더명!' + 경로_변수와 같은 방식으로는 사용 불가능하다.
  • 따라서 로더를 통해서 무언가를 불러올 때는 변수에 따라 변동되는 대상을 로드할 수 없으며 불러올 대상이 문자열로 하드코딩 되어 있어야 한다는 제약이 있다.
  • 이런 제약 때문에 다음과 같은 템플릿 구성이 불가능하다.
<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Webpack App</title>
    </head>
    <body>
        <%= require('!!underscore-template-loader!'+ htmlWebpackPlugin.options.bodyFilePath) %>
    </body>
</html>
  • 예를 들어 htmlWebpackPlugin.options.bodyFilePath의 값이 ./body.html이라고 해 보자.
  • '!!underscore-template-loader!'+ htmlWebpackPlugin.options.bodyFilePath 이런식으로 쓰게 되면 require 함수는 !!underscore-template-loader!로더로 불러오는 ./body.html이라는 방식으로 판단하지 않고 !!underscore-template-loader!./body.html라는 경로를 불러오는 방식으로 판단한다. 하지만 !!underscore-template-loader!./body.html 이런 경로는 존재하지 않기 때문에 모듈을 불러올 때 에러가 발생하게 된다.
  • 웹팩에서 어떤 대상 경로에 로더를 적용하여 불러오기 위해서는 변수 없는 문자열로 정의해 주어야 한다.