sharingStorage

모던 자바스크립트 49장 Babel과 Webpack을 이용한 ES6+ / ES.NEXT 개발환경 구축 본문

Front-End/모던 자바스크립트 Deep Dive

모던 자바스크립트 49장 Babel과 Webpack을 이용한 ES6+ / ES.NEXT 개발환경 구축

Anstrengung 2022. 11. 22. 09:05

크롬, 사파리 파이어폭스, 엣지 같은 에버그린 브라우저의 ES6 지원율은 약 98%지만 IE 11의 지원율은 약 11%다. 그리고 매년 새롭게 도입되는 ES6이상의 버전과 제안 단계에 있는 ES제안 사양은 브라우저에 따라 지원율이 제각각이다. 

 

따라서 ES6+와 ES.NEXT의 최신 사양을 사용하여 프로젝트를 진행하려면 최신 사양으로 작성된 코드를 경우에 따라 IE를 포함한 구형 브라우저에서 문제 없이 동작시키기 위한 개발 환경을 구축하는 것이 필요한다.

 

또한 대부분의 프로젝트가 모듈을 사용하므로 모듈 로더도 필요하다. ES6모듈은 대부분의 브라우저에서 사용가능하지만 다음과 같은 이유로 아직 별도의 모듈 로더를 사용하는 것이 일반적이다

  • IE를 포함한 구형 브라우저는 ESM을 지원하지 않는다.
  • ESM을 사용하더라도 트랜스파일링이나 번들링이 필요한 것은 변함이 없다.
  • ESM이 아직 지원하지 않는 기능이 있고 몇가지 이슈가 존재한다.

 

해서 이번엔 Babel과 Webpack을 이용해 ES6+/ ES.NEXT의 개발환 경을 구축해보고 트랜스파일링하는 방법도 알아볼 것이다.

 

내가 사용한 Node와 npm 버전이다.

NodeJS: 14.16.2
npm: 8.3.0

책과 같은 오류가 뜨지 않을 때도 있으니 오류를 직접 경험해보려면 책과 같은 버전인 NodeJS 14.3.0 / npm 6.14.5 버전을 사용하는 것도 추천한다. (크게 다르지 않다.) 

 

 

49.1 Babel 

화살표 함수(ES6)나 지수 연산자(ES7)을 사용하는 경우 IE같은 구형 브라우저에선 지원하지 않을 수 있다. Babel을 사용하면 위의 코드를 다음과 같이 ES5사양으로 변환할 수 있다.

 

 

49.1.1 Babel 설치

npm을 사용하여 Babel을 설치해보자. 터미널에 다음과 같은 명령어를 입력한다.

mkdir은 파일을 만드는 리눅스 명령어, cd는 esnext~~(이하 디렉토리 이름)에 위치로 이동하는 명령어이다.

 

 

Babel, Webpack, 플로그인 버전은  빈번하게 업그레드 되므로 만약  특정 버전을 설치하고 싶으면 패키지 이름뒤에 @버전을 붙이면 된다.

 

 

49.1.2 Babel 프리셋 설치와 babel.config.json 설정 파일 작성

Babel을 사용하려면 @babel/preset-env를 설치해야한다. @babel/preset-env는 함께 사용되어야 하는 Babel플러그인을 모아 둔 것으로 Babel 프리셋은 다음과 같다.

  • @babel/preset-env
  • @babel/preset-flow
  • @babel/preset-react
  • @babel/preset-typescript

babel/preset-env 프로젝트 환경에 맞춰 필요한 플러그인들을 동적으로 결정해준다. 프로젝트 지원환경은  .browserlistrc파일에서 상세히 설정할 수 있다.

 

 

기본설정으로 babel프리셋을 설정한다.


설칠가 완료된 이후 package.json파일 

 

설치가 완료되면 babel.config.json 설정 파일 생성후 다음과 같이 작성한다.

@bable/preset-env를 사용하겠다는 의미다.

 

49.1.3 트랜스파일링

Babel을 사용하여 ES6+사양의 코드를 ES5사양의 코드로 트랜스파일링 해본다.

매번 Bable CLI 명령어를 입력하는 것은 번거로우므로 package.json 파일에 scripts를 추가한다.

babel 명령어를 등록하기위해 package.json 파일에 scripts추가

위 scripts에 build는 src/js 폴더에 모든 자바스크립트 파일을 트랜스파일링 한후 그 결과물은 dist.js폴더에 저장한다.

  • -w : 타킷 폴더에 있는 자바스크립트 파일들의 변경을 감지하여 자동 트랜스파일
  • -d : 트랜스파일링된 결과물이 저장될 폴더를 지정, 폴더가 없으면 자동 생성

 

 

ES6+/ ES.NEXT 사양의 자바스크립트 파일

lib.js
main.js

 

터미널에서 다음과 같은 명령어로 트랜스파일링을 실행한다.

성공적으로 완료 설치한 babel의 버전이 높아서 구버전에서 발생하는 오류인 클래스 필드정의제안과 객체 Rest/Spread 프로퍼티 제인 오류가 발생하지 않았다.

 

 

 

49.1.4 Babel 플러그인 설치

설치가 필요한 Babel 플러그인은 Babel 홈페이지에서 검색할 수 있다. class field를 검색하여 public/private 클래스 필드를 지원하는 @babel/plugin-proposal-class-properties를 설치한다.

현재 버전(2022)에서는 babel/plugin-proposal-class-properties가 prrset-env에 포함되어 있다고 한다.(오류가 안뜬 이유)

 

 

설치가 완료된 후 package.json파일

 

설치한 플러그인은 babel.config.json 설정 파일에 추가해야한다. 다음과 같이 수정한다.

 

트랜스파일링에 성공한 dist/js폴더에 존재하는 main.js 파일 결과

 

 

49.1.5 브라우저에서 모듈 로딩 테스트

위 예제는 es6의 모듈의 import와 export 키워드를 require, exports로 트랜스 파일링 되는 것 과 같은 과정을 통해 정상적으로 작동하는 것을 확인했다.

 

위 예제의 모듈 기능은 Node.js 환경에서 동작한 것이고 Babel이 모듈을 트랜스파일링한 것도 Node.js가 기본 지원하는 CommonJS방식의 모듈 로딩 시스템을 따른 것이다. 

브라우저는 CommonJS방식의 require 함수를 지원하지 않으므로 위에서 트랜스파일링된 결과를 그대로 브라우저에서 실행하면 에러가 발생한다. 프로젝트 루트 폴더에 다음과 같이 index.html을 작성하여 트랜스파일링된 자바슽크립트 파일을 브라우저에서 실행해보았다.

브라우저의 ES6모듈(ESM)을 사용하도록 Babel을 설정할 수 있지만 ESM을 사용하는 것은 문제가 있을 수 있다. 이때 사용하는 것이 Webpack이다.

 

 

49.2 Webpack

Webpack은 의존 관계에 있는 자바스크립트, CSS, 이미지 등의 리소스들을 하나(또는 여러 개)파일로 번들링하는 모둘 번들러다. Webpack을 사용하면 의존 모듈이 하나의 파일로 번들링되므로 별도의 모듈 로더가 필요없다.

그리고 여러개의 자바스크립트 파일을 하나로 번들링하므로 HTML파일에서 script 태그로 여러 개의 자바스크립트 파일을 로드해야 하는 번거로움도 사라진다.

 

이제부턴 Webpack과 Babel을 이용해 ES6+/ ES.NEXT 개발 환경을 구축하여 보자. Webpack이 자바스크립트 파일을 번들링하기 전에 Babel을 로드하여 ES6+/ES.NEXT 사양의 소스코드를 ES5 사양의 소스코드로 트랜스파일링하는 작업을 설정할 것이다.

 

 

49.2.1 Webpack 설치

터미널에서 다음과 같이 명령어를 입력한다.

 

설치가 완료된 이후 package.json 파일

 

 

49.2.2 babel-loader 설치

Webpack이 모듈을 번들링할 때 Babel을 사용하여 ES6+/ ES.NEXT 사양의 소스코드를 트랜스파일링하도록 babel-loader를 설치한다. 

npm install --save-dev babel-loader

그 후 package.json파일에 npm scripts를 변경하여 Babel대신 Webpack을 수행하도록 한다.

npm build 명령어 변경

 

 

49.2.3 webpack.config.js 설정 파일 작성

webpack.config.js는 Webpack이 실행될 때 참조하는 설정 파일입니다. 프로젝트 루트 폴더에 webpack.config.js 파일을 생성하고 다음과 같이 작성합니다.

작성후 npm run build 명령 실행

 

왜인지 babel/presets-env를 찾을 수 없다해서 package.json파일을 확인한 결과 dependencies에 babel/presets-env가 존재하지 않았다. 다시 한번 설치 진행하고 package.json을 확인했다.

 

그후 다시 npm run build 명령을 실행하면 bundle.js 파일이 생성되고 수정한 test.html이 정상적으로 작동하는 것을 볼 수 있다.

 

 

 

49.2.4 babel-polyfill 설치

만약 ES6에서 추가된 Promise, Object.assign, Array.from 등이 존재한다면 어떻게 될까?

이는 ES5 사양에 대체할 기능이 없기 때문에 트랜스파일링되지 못하고 그대로 남는다.

main.js를 다음과 같이 수정해서 Promise, assign 등이 어떻게 트랜스 파일링 되는지 확인해보자

이처럼 Promise, Object.assign, Array.from 등과 같이 ES5사양으로 대체할 수 없는 기능은 트랜스 파일링되지않는다. 따라서 IE같은 구형 브라우저에서도 위 기능을 사용하려면 @babel/polyfill을 설치해야한다.

설치 완료 후 package.json 파일은 다음과 같다.

@babel/polyfill은 개발환경에서만 사용하는 것이 아니라 실제 운영환경에서도 사용해야 한다. 따라서 개발 의존성으로 설치하는 --save-dev 옵션을 지정하지 않는다.

 

ES6의 import를 사용하는 경우 import보다 먼저(진입점의 선두에서) 폴리필을 로드하도록 한다.

Webpack을 사용하는 경우에는 위 방법 대신 webpack.config.js파일의 entry 배열에 폴리필을 추가한다.

 

 

4번째줄 폴리필이 추가된 것을 확인할 수 있다.

잘 작동하는 것으로 이번 글을 마치도록 하겠다.

Comments