본문 바로가기

IT Study./Do it! Vue.js 입문

7장. Vue.js 고급 개발자 되기 - 2

 

7장 - 2

 

 

 


07-2 뷰 개발을 위한 웹팩  

  • 05-2에서 잠깐 알아본 웹팩(webpack)최신 프런트엔드 프레임워크인 앵귤러, 리액트, 뷰에서 모두 권하는 모듈 번들러이다.
  • 뷰 프레임워크를 처음 배우는 입장에서는 웹팩에 대해 깊이 알 필요는 없다. 다만 이게 무엇이고 왜 필요한지 정도는 알고 있어야 나중에 필요할 때 직접 찾아 볼 수 있으므로 웹팩에 대해 간단히 알아보고, 뷰 CLI로 생성한 프로젝트에서 사용하는 웹팩 데브 서버와 웹팩 설정 파일(webpack.config.js)에 대해 살펴보자.

 

<웹팩이란?>

  • 웹팩은 흔히 모듈 번들러라고 알려져 있고, 공식 홈페이지에서도 모듈 번들러라고 부르고 있다.

웹팩의 소개 이미지(출처 : 웹팩 공식 사이트 https://webpack.github.io/)

  • 여기서 '모듈이 무엇이고, 번들러는 무엇인가?'라는 의문을 가질 수 있다.
  • 공식 홈페이지에서는 웹팩을 '서로 연관이 있는 모듈 간의 관계를 해석하여 정적인 자원으로 변환해 주는 변환도구'라고 정의한다.
  • 이를 좀 더 쉽게 풀어 설명하면 '파일 간의 연관 관계를 파악하여 하나의 자바스크립트 파일로 변환해 주는 변환 도구'이다.

 

  • 물론 웹팩의 플러그인 기능을 활용하면 1개 이상의 자바스크립트 파일 또는 CSS, HTML 파일을 추가로 생성할 수는 있다. 다만 기본적인 취지 자체는 '애플리케이션 동작과 관련된 여러 개의 파일(HTML, CSS, 자바스크립트, 이미지 등)들을 1개의 자바스크립트 파일 안에 다 넣어 버리고, 해당 자바스크립트 파일만 로딩해도 웹 앱이 돌아가게 하자'는 것이다.

 

  • 가장 중요한 건 '왜 모든 파일의 내용을 1개의 파일에 담느냐?'이다. 이 부분은 웹 앱의 로딩 속도를 향상시키는 것과 연관이 있다. 일반적으로 웹 페이지를 브라우저에 나타내기 위해 웹 화면을 구성할 때 화면 구성에 필요한 자바스크립트, CSS, 이미지 파일마다 서버로 보내는 HTTP 요청이 발생한다. 따라서 HTTP 네트워크 요청 숫자가 늘어나면 늘어날수록 웹 화면 로딩 시간은 길어질 수밖에 없다.

 

  • 예를 들어, HTTP 요청 1개에 2초가 소요된다고 하면 1개의 파일 요청과 30~40개의 파일 요청은 느린 인터넷 환경에서 최소 1분의 차이가 난다. 그러므로 당연히 HTTP 요청 숫자를 줄여야 웹 페이지 로딩이 빨라지고, 이는 결국 더 나은 사용자 경험을 제공하는 결과로 이어진다. 이런 문제를 개선하기 위해 예전부터 걸프(Glup), 그런트(Grunt)와 같은 웹 자동화 도구들이 존재했으며, 최근에는 이 도구들보다 더 많은 기능을 추가로 제공하는 웹팩이 등장했다.
    • 걸프와 그런트에 대해 더 알고 싶다면 검색 엔진에 'gulp tutorial', 'grunt tutorial'을 검색해 보아라.

 

<웹 팩의 주요 속성>

  • 웹팩을 사용할 때 알아둬야 하는 주요 속성은 아래와 같이 크게 5가지이다.
속성 설명
entry 웹팩으로 빌드(변환)할 대상 파일을 지정하는 속성이다. entry로 지정한 파일의 내용에는 전체 애플리케이션 로직과 필요 라이브러리를 로딩하는 로직이 들어간다.
output 웹팩으로 빌드한 결과물의 위치와 파일 이름 등 세부 옵션을 설정하는 속성이다.
loader 웹팩으로 빌드할 때 HTML, CSS, PNG(이미지) 파일 등을 자바스크립트로 변환하기 위해 필요한 설정을 정의하는 속성이다.
plugin 웹팩으로 빌드하고 나온 결과물에 대해 추가 기능을 제공하는 속성이다. 예를 들어, 결과물의 사이즈를 줄이거나 결과물(기본적으로 자바스크립트)을 기타 CSS, HTML 파일로 분리하는 기능 등이 있다.
resolve 웹팩으로 빌드할 때 해당 파일이 어떻게 해석되는지 정의하는 속성이다. 예를 들어, 특정 라이브러리를 로딩할 때 로딩할 때 버전은 어떤 걸로 하고, 파일 경로는 어디로 지정하는지 등을 정의한다.

 

<웹팩 데브 서버>

  • 웹팩 데브 서버(webpack-dev-server)란 웹팩 설정 파일의 변화를 감지하여 빠르게 웹팩을 빌드할 수 있도록 지원하는 유틸리티이자 노드제이에스(Node.js)서버이다.
  • 웹팩 데브 서버는 웹팩 설정 파일의 내용이 변경되면 브라우저 화면을 자동으로 새로 고침하고, 바로 다시 웹팩으로 빌드하는 기능을 갖고 있다.
  • 따라서 웹팩으로 화면을 빠르게 제작하고자 할 때 유용하게 사용할 수 있다.

 

  • 05-2에서 배운 뷰 CLI로 webpack-simple 프로젝트를 생성하고, npm install 명령어로 필요한 라이브러리를 설치한 후 npm run dev 명령어를 실행하면 아래와 같은 결과가 출력된다.

npm run dev 명령어의 실행 결과

  • 첫 번째 줄은 웹팩 데스 서버가 노드로 로컬 서버 하나를 띄워 http://localhost:8080에 프로젝트를 실행하고 있다는 의미이다.
  • 두 번째 줄은 /dist/에 있는 웹팩 결과물로 웹 앱을 로딩하고 있다는 의미이다.

 

  • 그런데 사실 웹팩을 빌드하려면 npm run build라는 명령어를 사용해야 한다.
  • 이 명령어가 아닌 npm run dev 명령어를 사용했는데도 현재 애플리케이션은 마치 웹팩으로 빌드한 결과물을 정상적으로 실행하고 있는 것처럼 동작한다. 아래의 프로젝트 구조를 살펴보자.

npm run dev(왼쪽), npm run build(오른쪽)

  • 왼쪽 그림을 보면 npm run dev 명령어로 프로젝트를 실행했을 떄는 프로젝트 구조에 /dist/라는 폴더는 존재하지 않았다. 존재하지도 않는 폴더의 내용을 차고하고 있는 것이다.
  • 결론적으로 npm run build 명령어로 /dist/라는 웹팩 빌드 결과물을 만들지 않아도 npm run dev 명령어를 실행했을 때 마치 웹팩으로 빌드한 것과 같은 효과를 얻게 된다는 것을 알 수 있다.

npm run build 명령어를 실행하면 생성되는 빌드 결과물

  • 그렇다면 npm run dev 명령어로 띄운 서버에서 참조하고 있는 빌드 결과물은 어디 있을까? 바로 메모리 상에 있다.
  • 웹팩 데브 서버는 빌드한 파일을 파일 시스템에 저장하지 않고 컴퓨터 메모리에만 저장하기 때문에 파일 시스템(폴더)상에서는 빌드 파일을 확인할 수 없다.
  • 이렇게 하는 이유는 파일 시스템에 파일을 쓰고 읽는 시간보다 메모리에 저장하고 읽는 시간이 더 빠르기 때문이다. 그래서 웹팩 데브 서버를 인 메모리(in memory) 기반이라고 말한다.

 

<webpack-simple 프로젝트의 웹팩 설정 파일 분석>

  • 뷰 CLI로 webpack-simple 프로젝트를 생성하고 나면 프로젝트 최상위 레벨에서 webpack.config.js라는 웹팩 설정 파일을 확인할 수 있다.
  • 뷰 애플리케이션을 실행하기 위해 npm run dev 명령어를 입력했을 때 webpack.config.js 파일에 정의된 설정에 따라 .vue 파일을 포함한 기타 파일들이 웹팩으로 빌드가 된다.
  • 수려한 화면 UI를 위해 외부 라이브러리를 사용하거나 기타 기능들을 결합하려면 웹팩 설정을 변경해 줘야 하기 때문에 웹팩 설정 파일에 대해 이해해 두는 것이 좋다.

 

  • webpack.config.js 파일을 첫 줄 부터 순서대로 살펴보자.

 

파일 경로와 웹팩 라이브러리 로딩

var path = require('path')
var webpack = require('webpack')
  • output 속성에서 사용할 노드 path 라이브러리와 웹팩 플러그인에서 사용할 node_modules의 웹팩 라이브러리를 node_modules 폴더에서 로딩하여 path, webpack에 각각 저장한다.

 

entry 속성

entry: './src/main.js'
  • 웹팩으로 빌드할 파일을 src 폴더 밑의 main.js 파일로 지정한다. main.js 파일에 정의한 내용에 따라 애플리케이션의 구성 요소 및 파일들이 웹팩으로 번들링(build)된다.

 

output 속성

output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
}
  • 웹팩으로 빌드를 하고 난 결과물 파일의 위치와 이름을 지정한다. 결과물 파일의 위치는 dist/build.js이다.

 

module 속성

  • 웹팩으로 애플리케이션 파일들을 빌드(변환)할 때 HTML, CSS, PNG(이미지)등의 파일을 자바스크립트로 변환해 주는 로더를 지정한다.
module: {
    rules: [
      {
        test: /\.css$/, // 1.
        use: [
          'vue-style-loader',
          'css-loader'
        ],
      },      {
        test: /\.vue$/, // 2.
        loader: 'vue-loader',
        options: {
          loaders: {
          }
          // other vue-loader options go here
        }
      },
      {
        test: /\.js$/, // 3.
        loader: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|gif|svg)$/, // 4.
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      }
    ]
},
  • 위 코드에 있는 각 번호의 설명은 아래와 같다.
    1. 프로젝트 폴더 안의 css 파일에 vue-style-loader와 css-loader를 적용한다. css-loader를 적용하여 css 파일을 모두 자바스크립트로 변환한다. 그리고 앞에서 변환된 css 속성들이 최종적으로 vue-style-loader을 거쳐 index.html에 <style> 태그로 삽입된다.
    2. vue 파일에는 vue-loader를 적용한다. vue 파일의 <template>, <script>, <style> 등의 내용이 자바스크립트로 변환되어 웹팩 빌드 결과물에 포함된다.
    3. 자바스크립트 파일에 babel-loader를 적용한다. 자바스크립트 파일의 ES6 문법을 모든 브라우저에서 호환 가능한 자바스크립트로 변환(transpile)한다.
    4. 이미지 파일들은 file-loader를 이용하여 자바스크립트 파일로 변환한다.

 

resolve 속성

resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['*', '.js', '.vue', '.json']
},
  • 웹팩으로 빌드할 때 뷰 라이브러리의 여러 유형 중 어떤 걸 선택할지 지정한다. 여기서 설정된 vue.esm.js는 최신 웹팩 버전과 같이 사용할 수 있는 Full 버전의 라이브러리를 의미하며, 이렇게 별도로 설정하지 않으면 런타임 버전인 vue.runtime.esm.js를 사용한다.

 

devServer 속성

devServer: {
    historyApiFallback: true,
    noInfo: true,
    overlay: true
},
  • 웹팩 데브 서버 관련 속성을 지정한다. historyApiFallback 속성은 클라이언트 사이드 라우팅인 뷰 라우터와 함께 사용하기 위해 true로 지정한다. noInfo 속성은 처음 서버를 시작할 때만 웹팩 빌드 정보를 보여주고, 이후 변경 시에는 빌드 정보를 보여주지 않는다. overlay 속성은 웹팩으로 빌드할 때 오류가 있으면 브라우저 화면 전체에 오류를 표시한다.

 

performance 속성

performance: {
    hints: false
},
  • 웹팩으로 빌드한 파일의 크기가 250kb를 넘으면 경고 메시지를 표시할지를 설정한다. hints가 false이므로 크기와 관계 없이 경고가 표시되지 않는다.

 

devtool 속성

devtool: '#eval-source-map'
  • 웹팩으로 빌드된 파일로 웹 앱을 구동했을 때 개발자 도구에서 사용할 디버깅 방식을 지정한다. 옵션이 여러 가지이므로 자세한 내용은 https://webpack.js.org/configuration/devtool/를 참고하라.
 

Devtool | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

 

배포할 때 옵션

  • 애플리케이션의 기능과 화면을 구현한 후 최종적으로 사용자나 사이트에 배포할 때 애플리케이션의 성능 향상을 위해 추가한 설정이다.
if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map' // 1.
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({ // 2. 시작
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    }) // 2. 끝
  ])
}
  • 위 코드에서 각 번호에 해당하는 설명은 아래와 같다.
    1. 개발자 도구 분석 옵션을 #source-map으로 지정한다.
    2. 자바스크립트 파일의 크기를 줄이는 Uglify 플러그인과 환경 변수 값을 설정한다.

 

  • 앞에서 다룬 속성들 중 entry, output, loader, plugin, resolve 속성은 중요하므로 꼭 기억해 두는 것이 좋다.
  • 그럼 웹팩 설정 파일의 속성들이 실제로는 어떻게 동작하는지 확인해 보자.
  • 아래의 프로젝트 폴더를 기준으로 빌드 과정을 도식화한 그림을 보자.

웹팩으로 빌드할 때 파일 간의 관계도

  • 앞의 프로젝트는 main.js 파일에서 App.vue 파일과 Vue.js 라이브러리를 불러와서 애플리케이션을 동작시키고, 또 App.vue에서 logo.png 파일을 이용하여 웹 페이지를 구성하는 구조이다.
  • 따라서 웹팩으로 빌드할 때 파일 간의 관계에 따라 bulid.js 파일을 생성한다. 생성된 build.js는 애플리케이션 구조대로 파일(모듈) 간의 순서가 알맞게 설정되어 있다.
  • 결론적으로, index.html 파일에서 웹팩으로 빌드한 build.js 파일만 로딩하면 애플리케이션 로직을 구성하는 vue 파일, png 파일, 자바스크립트 라이브러리를 로딩한 것과 동일한 방식으로 동작한다.

 

 

 


해당 글은 [Do it! Vue.js 입문] 책을 토대로 공부한 내용을 기록하기 위하여 작성됨.