코린이의 개발 일지

[웹 web] - WebPack, babel 사용하기 (설치, 사용 방법(코드)) 본문

웹 (web)

[웹 web] - WebPack, babel 사용하기 (설치, 사용 방법(코드))

폴라민 2022. 9. 11. 21:02
반응형

webpack 사용하기

Bundler

등장 배경

  • 서버와의 접속이 많을 수록 애플리케이션은 느리게 로딩
  • 서로다른 js 파일에서 같은 변수를 사용하게 될 경우 애플리케이션 충돌이 발생하게 됨.

이러한 문제들을 해결하기 위해 등장한 도구들을 Bundler라고 한다.

⇒ 여러개의 파일을 묶어주는 도구

Bundler 종류

  • webPack
  • Broserify
  • Parcel

 

webpack 설치

npm init
npm install -D webpack webpack-cli

 

configration 설정

webpack.config.js 파일 만들기

  • 파일 내부 기본 골격
import path from 'path';
import nodeExternals from 'webpack-node-externals';

export default {
  mode: 'development',
  entry: './public/javascripts/index.js',
  output: {
    path: path.join(path.resolve(), 'public/dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
        {
            test: /\\.css$/i,
            use: [
                'style-loader',
                'css-loader'
            ],
        },
        { 
            test: /\\.ejs$/, 
            use: 'ejs-loader?variable=data' 
        },
    ],
  },
  devtool: 'eval-source-map',
  externals: [nodeExternals()]
};

 

webpack-node-externals 설치

npm install -D webpack-node-externals

왜 쓸까?

  • node.js로 프로젝트를 개발하게 되면 다양한 라이브러리들을 필요로 하게 되는데, 이러한 라이브러리들을 관리하기 위해 yarn이나 npm같은 패키지 매니저들을 사용한다.
  • webpack-node-externals 는 webpack의 번들링 과정에서 외부 모듈을 제외할 수 있게 해주는 패키지이다.
  • 따라서 해당 패키지를 사용하게 되면 번들링 시 외부 모듈들의 의존성을 끊고 순수하게 내가 작성한 파일들만 번들링해준다.
  • 만약 babel 설정을 할 예정이라면 쓰면 안된다. (글 하단에 의문점 참고)
    • 간단히 얘기하면 해당 모듈은 백엔드에서만 사용한다고 한다.

 

loader 사용하기

css loader 설치

npm install -D style-loader css-loader

ejs loader 설치

npm install -D ejs-loader

주의할 점

로더는 기본적으로 오른쪽에서 왼쪽 순으로 적용

module: {
  rules: [
    {
      test: /\\.scss$/,
      use: ['style-loader', 'css-loader', 'sass-loader']
    }
  ]
}

이 외에도 다양한 loader들이 있다.

출처:

https://joshua1988.github.io/webpack-guide/concepts/loader.html#loader

 

plugin 사용하기

html-webpack-plugin 설치

npm install -D html-webpack-plugin
  • 기능

script 태그를 사용해서 body에 모든 webpack 번들을 포함하는 HTML5 파일을 생성

  • 출처

https://webpack.kr/plugins/html-webpack-plugin/

 

실행

npx webpack --watch

 

 

Babel 사용하기

Babel이 뭘까?

  • 자바스크립트 컴파일러
  • 정확히는 javascript로 결과물을 만들어주는 컴파일러

자바스크립트로 변환하는 과정이 왜 필요할까

  • 새로운 ESNext 문법을 기존의 브라우져에 사용하기 위해 babel은 필수적
  • 사용자마다 브라우저 버전도 다르고 OS 버전도 다르기 때문에
  • 타입 스크립트도 변환해줌

Polyfill이란?

  • polyfill은 개발자가 특정 기능이 지원되지 않는 브라우저를 위해 사용할 수 있는 코드 조각이나 플러그인을 의미
  • 브라우저에서 지원하지 않는 기능들에 대한 호환성 작업을 채워 넣는다고 해서 polyfill이라고 칭한다.

babel-polyfill

  • babel은 이러한 polyfill을 손쉽게 지원하기 위해 babel-polyfill기능을 지원

즉 babel을 사용한다고 해서 최신 함수를 사용할 수 있는 것은 아니다.

babel은 문법을 변환하여 자바스크립트로 변환하는 transpiler 역할만 할 뿐.

polyfill은 프로그램이 처음에 시작될 때 지원하지 않는 기능을 추가하는 것.

💡 babel은 컴파일 시에 실행되고 babel-polyfill은 런타임에 실행된다.

 

설치 방법

npm install -D babel-loader @babel/core @babel/preset-env
npm install --save-dev @babel/plugin-transform-runtime
npm install -D @babel/runtime-corejs3

 

webpack.config.js 파일 (최종)

import path from 'path';

export default {
  mode: 'development',
  entry: './public/javascripts/index.js',
  output: {
    path: path.join(path.resolve(), 'public/dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
        {
            test: /\\.css$/i,
            use: [
                'style-loader',
                'css-loader'
            ],
        },
        { 
            test: /\\.ejs$/, 
            use: 'ejs-loader?variable=data' 
        },
        {
          test: /\\.m?js$/,
          exclude: /(node_modules)/,
          use: {
            loader: 'babel-loader',
          }
        }
    ],
  },
  devtool: 'eval-source-map',
};

 

babel.config.json

{
    "presets": [
        ["@babel/preset-env"]
    ],
    "plugins": [["@babel/plugin-transform-runtime",{"corejs":3}]]
}

 

 

의문점

아니 왜 babel 사용하면 externals: [nodeExternals()]를 쓰면 안되는 거지..?

아까 맨 처음 webpack.config.js에서 처럼 마지막줄에

  devtool: 'eval-source-map',
  externals: [nodeExternals()]
};

external을 통해 외부모듈을 제외 시키면

webpack : Uncaught ReferenceError: require is not defined

이런 오류가 난다.

이렇게

 

 

스택오버플로우에 나와 같은 사람이 있어서 가져와 봤는데 당최 이해가 안간다.

출처:

https://stackoverflow.com/questions/45818937/webpack-uncaught-referenceerror-require-is-not-defined

 

 

내용에 따르면 webpack-node-externals는 오직 백엔드에서만 사용된다고 한다. 따라서 web app에서는 externals: [nodeExternals()]를 지워야 한다고 한다.

만약 위의 명령을 web app에서 쓰려면 오직 require만 사용해서 commonJS 모듈을 가져와야 한다고 한다.

 

그래 여기까지는 좋다 이해했다.

근데 babel 설정하기 전에 webpack만 설정했을 때는 분명 externals를 안썼을 때, 30개가 넘는 오류가 났다. 외부 모듈들 때문에.

근데 왜 babel 설정하니까 외부모듈로 인한 오류가 또 안나네…?

 

 

여기서부터는 내 추측이다.

babel 설정 전이나 후나 내 코드는 모두 es6 문법이었다.

 

그러므로 babel 설정 전, webpack만 설정했을 때는

es6 문법으로 동작하는 과정에서 require로만 동작하는 commonJS 모듈들이 자동으로 안가져와짐.

따라서 오류가 발생하는 commonJS 모듈들을 externals: [nodeExternals()]로 제외시켜야 했음.

 

babel 설정 이후,

babel이 자동으로 모든 최신 문법들을 commonJS 문법으로 바꿔줌 (require 잘 동작)

따라서 굳이 외부 모듈 제외 시키지 않아도 외부모듈에서 오류가 나지 않음

이렇게 생각해봤는데 좀 더 알아봐야겠다.

반응형
Comments