[FE]WebPack

HOU·2022년 7월 19일
3

frontend

목록 보기
9/13

Webpack? Bundler?

웹팩을 알기전에 번들러에대해 알아야한다.
웹사이트를 구성할때 .js .css .images 파일등 수 많은 파일들이 모여서 웹사이트를 구성하게 되는데 이런 파일들이 모여서 웹사이트가 느리게 로딩이 된다. 또한 많은 자바스크립트등을 사용하다보면 각각의 패키지들이 같은 이름이나 함수를 사용하게 되면서 애플리케이션이 깨지게 되는데, 이런 현상을 해결하기 위해 나온 개념이 묶는다는 개념의 번들러가 등장하였다.

Webpack이란?

  • Webpack = 모듈 번들링이라고 한다.
  • 웹 에플리케이션을 구성하는 자원(HTML, CSS, Javscript, Images 등)을 각각의 모듈로보고 이를 조합해서 하나의 결과물로 만드는 과정
  • 웹에서 사용하는 모든 자원(assets)를 번들링 해주는 도구.

간단하게! 여러 파일을 하나의 파일로 합쳐주는 자바스크립트 번들러이다.

웹팩의 등장 배경

인터넷의 발전으로 웹 어플리케이션의 복잡도가 등장하면서 코드의 양이 방대해지고 이런 코드를 쉽게 유지보수 하기 위해서 모듈로서 관리하는 방법이 필요하게 되었다. ES6 이전에 모듈을 관리하는 방법으로 AMD , CommonJS등이 존재했지만 하나의 표준이 아닌 사용하는 사람에 따라서 원하는 것을 사용해 왔다.
그 후에 ES6 이후부터 자바스크립트에서 표준 모듈 시스템을 제안하였고 이것이 export/import 방식이다.
하지만 모든 브라우저에서 ES6방식의 모듈 시스템을 지원하지는 않았다. 따라서 개발자들은 브라우저와 버전에 상관없이 편리한 모듈 시스템을 사용하기 원했고 이러한 배경에 등장한 것이 웹팩이다.

위에 내용을 정리하자면 3가지로 정리할 수 있다.
1. 파일 단위의 자바스크립트 모듈 관리의 필요성
2. 웹 개발 작업 자동화 도구 (WebTaskManager)
3. 웹 애플리케이션의 빠른 로딩 속도와 높은 성능

Webpack을 사용하는 이유

  • 예전에는 페이지마다 새로운 html을 요청해서 뿌려 주는 방식이라면, 요새는 SPA( 하나의 html페이지에 여러개의 자바스크립트 파일들이 포함된다.) 연관 되어 있는 자바스크립트 종속성 있는 파일들을 하나의 파일로 묶어줘서 관리하기 편한다.

  • 파일을 컴파일 할 때, 여러 모듈들의 파일을 읽어오는데 시간이 오래 걸린다. 그부분을 해결하기 위해 여러 파일을 하나의 파일로 번들링 해준다.

  • 하나의 자바스크립트 파일로 만들어서 웹페이지 성능 최적화

  • 중복된 소스코드를 최소화 하고 모듈 개념을 사용해서 글로벌이 오염되지 않는다.


Webpack에서 제일 유명한건 babel이다. 그럼 babel은 무엇일까?

Babel이란?

  • Ecmasciprt6를 Ecmascript5로 변환해준다.

Babel을 사용하는 이유

  • 최신 업데이트 중에 ES6 버전은 큰 업데이트 부분을 차지한다. 크게 일어난 만큼 ES6를 지원해주는 브라우저가 있다. 그 중에서는 지금까지는 크롬, 사파리, 파이어폭스 와 같은 에버그린 브라우저는 최신 업데이트 버전으로 지원을 해준다. 하지만 인터넷익스플로러 (현재 사망) 를 사용하는 비율도 11프로나 되는데 지원을 하지 않는다. 그러므로 아직 구버전을 사용하는 ES5버전으로 변경해줘야 한다.

  • 그래서 개발 환경을 설정할 때, webpack이랑 babel로 기초 환경 설정을 잡고 개발을 해야한다.

웹팩, 바벨 기초환경 세팅

$npm init -y
$npm install wepback --save-dev

만약 웹팩 v4 혹은 이후 버전을 사용한다면, CLI도 설치해야한다.

$npm install --save-dev webpack-cli

패키지를 설치했으면, 제대로 성공 되었는지 확인 해보자

$.\node_modules\.bin\webpack -v

웹팩의 핵심 요소

  1. Entry
  2. Output
  3. Loader
  4. Plugin

Entry

엔트리 속성은 웹 팩에서 웹 자원을 변환하기 위해 필요한 최초 진입점이다. 즉 Entry로 묶고자 하는 파일의 첫번째 진입점을 설정해주면 된다.

//webpack.config.js
//SPA(Single Page Application)
module.exports = {
  entry:'./src/index.js'
}

//Multi Page Application (MPA)
module.exports = {
  entry: {
    login: './src/LoginView.js',
    main: './src/MainView.js'
  }
}

이때 최초 집입점이 되는 파일 /index.js 파일은 웹애플리케이션의 전반적인 구조와 내용이 담겨있어야한다. 그래야 웹팩이 해당 파일을 토대로 애플리케이션의 모듈들의 연관 관계에 대해 이해하고 분석하고 합치기 때문이다.

Output

웹팩을 실행하여 빌드하고 난 후 결과물의 파일 경로를 의미한다. filename속성은 웹팩으로 빌드한 파일의 이름을 의마하며 여러가지 옵션을 넣을 수 있고, path 속성은 해당파일의 경로를 의미한다.

여기서 path속성에서 사용된 메서드는 인자로 받은 경로를 조합하여 유효한 파일 경로를 만드는 Node.jsAPI라고 한다.

var path = require('path');

module.exports = {
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, './dist')
  }
}
/* Node.js API가 하는 역할은 아래 코드와 동일하다. */
output: './dist/bundle.js'

Loader

웹팩이 애플리케이션을 해석할 때 자바스크립트 파일이 아닌 HTML, CSS, Images, Font 등을 변환할 수 있게 도와주는 속성이다. 웹팩은 모든 파일을 모듈로 취급하여 관리하는데 사실상 자바스크립트 파일만 알고 있어 로더를 이용해 다른 파일들이 웹팩이 이해하게끔 변경해줘야 한다.

//app.js
import './common.css';

console.log('css loaded');
/* common.css */
p {
	color:blue;
}
//webpack.config.js
module.exports = {
 entry:'./app.js',
 output : {
   filename: 'bundle.js'
}
}

위 파일을 빌드하면 오류가 발생합니다.
Module parse failed: unexpected token
You may need an appropriate loader to andle this type, currently no loaders are configured to process this file

이유는 적절한 로더를 추가하지 않았기 때문입니다.

보통 사용되는 로더 종류는 아래와 같다.

  • CSS Loader
  • Babel Loader
  • Sass Loader
  • File Loader
  • Vue Loader
  • TS Loader
  • Style Loader

CSS / Sass 설치

style-loadercss-loader 는 같이 사용되며 모든 설치는 npm을 통해 설치를 진행한다.
npm install style-loader css-loader --save-dev

module.exports = {
  modules: {
    rules : [
      {test:/\.css$/, use:'css-loader'},
      { test:/\.ts$/, use:'ts-loader'},
	]
  }
}

위와 같이 rules라는 객체로 속성을 지정한다.
test : 로더를 적용할 파일 유형 (일반적으로 정규 표현식)
use : 해당 파일에 적용할 로더 이름

Plugin

웹팩의 기본적인 동작에 추가적인 기능을 제공하는 속성.
Loader랑 역할을 비교해보자면 로더는 파일을 해석하고 변환하는 과정에 관여하며, Plugin은 해당 결과물의 형태를 바꾸는 역할을 한다고 볼 수 있다.

  • HtmlWebpackPlugin: 웹팩으로 빌드한 결과물로 Html 파일을 생성해주는 플러그인
  • ProgressPlugin: 웹팩의 빌드 진행율을 표시해주는 플러그인
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin(),
    new webpack.ProgressPlugin()
    ]
}

정리

var path= require('path');

module.exports = {
  entry: './src/test.js',
  output: {
    filename: 'bundle.js',
    path : path.resolve(__dirname * '/build')
  },
  mode : 'none',
 module: {
   rules: [
     {
       test: /\.css$/,
       use: [
         'style-loader',
         'css-loader'
         ]
     }
     ]
 }
};

위에 처럼 설정파일을 webpack.config.js 파일을 설정해주면 된다.

Babel 세팅

npm install @babel/node
npm install @babel/preset-env
npm install @babel/core

명령어를 입력해 설치해준다.

설치 후 babel을 설치할 파일을 최상위 root에 만들어 준다. .babelrc 추가후 아래 소스 입력

{
	"presets" : ["@babel/preset-env"]
}

마지막 정리

웹팩으로 해결하려는 문제

  1. 자바스크립트 변수 유효 범위 문제
  • ES6의 모듈 문법과 번들링으로 해결
  1. 브라우저별 HTTP요청 숫자의 제약
  • TCP스펙에 따라 브라우저에서 한 번에 서버로 보낼 수 있는 HTTP요청 숫자는 제약되어 있음.
    http/2 에서는 하나의 커넥션에 동시에 여러 파일들을 요청할 수 있지만, Http/1.1ㅇ서는 하나의 커넥션에서 하나의 요청을 보내야한다. 그러므로 js파일이 10개인 경우 10번의 요청을 보내야하기 때문에 성능저하의 문제가 있다.
  1. 사용하지 않는 코드의 관리
  2. Dynamic Loading 및 Lazy Loading 미지원 문제
    이전에는 Require.js같은 라이브러리를 사용하지 않는 이상 동적으로 원하는 순간에 모듈을 로딩하는 것이 불가능했다. 웹팩에서는 Code Splitting기능을 이용하여 원하는 모듈을 원하는 타이밍에 로딩할 수 있다.

참조

yon3115님 벨로그
codermun-log님 티스토리

profile
하루 한 걸음 성장하는 개발자

0개의 댓글