모던 자바스크립트 개발 [3] – NPM, Parcel, Babel, Polyfill

NPM

  • npm은 node.js에서 사용하는 패키지 매니저이다. node.js를 설치할 경우 같이 설치된다.
  • npm을 시작하려면 프로젝트에서 npm init 명령어를 실행하자. 각종 configuration이 적힌 package.json 파일이 떨어진다.
  • 필요한 패키지를 다운받으려면 npm install {패키지 이름} 명령어를 사용하자. node_modules 폴더에 패키지가 설치되고, package.json에 dependencies에 자동으로 등록된다.
    • node_modules 폴더는 git ignore에 등록하자.
    • package.json 파일만 있으면 npm install 명령어로 dependencies 패키지를 모두 다운받을 수 있다.
  • npm으로 설치한 패키지는 보통 CommonJS 방식으로 import 해서 사용해야 하고, 배포하려면 번들링 작업이 필요하다.
  • ES 모듈 방식으로 사용하려면 ES 전용 모듈을 다운받자. (e.g. npm install lodash-es)
import cloneDeep from './node_modules/lodash-es/cloneDeep.js';

const state = {
  cart: [
    { product: 'bread', quantity: 5 },
    { product: 'pizza', quantity: 5 },
  ],
  user: { loggedIn: true },
};
const stateClone = Object.assign({}, state);
const stateDeepClone = cloneDeep(state); // deepcopy

state.user.loggedIn = false;
console.log(stateClone);

console.log(stateDeepClone);

Parcel을 활용한 번들링

  • parcel은 npm과 같은 ‘빌드 툴’의 일종이다.
    • npm i parcel --save-dev: –save-dev는 develop 환경에서만 필요한 패키지를 다운받을 때 사용하는 옵션
  • npx parcel index.html로 parcel을 사용해보자.
  • parcel을 사용할 경우 html 파일에서 <script type="module src=""></script> 과 같이 module 타입을 명시하고 모듈을 사용하는 방식이 더이상 동작하지 않는다.
  • parcel은 dist 폴더에 코드에 필요한 모듈을 정리해서 파일들을 만들고 번들링 해준다.
if (module.hot) {
  module.hot.accept();
}
  • 빠른 모듈 교체(HMR, Hot Module Replacement)는 런타임에 페이지 새로고침 없이 모듈을 자동으로 갱신해준다.
import cloneDeep from 'lodash-es';
  • parcel을 사용하면 위와 같이 패키지 이름만 명시해도 모듈을 불러올 수 있다.
  • 이미 설치 되지 않은 패키지라면 자동으로 설치해서 package.json dependencies에 추가된다.

NPM Scripts

  • package.json에 있는 scripts에 parcel 번들링 명령어를 작성하면 parcel을 편리하게 사용할 수 있다.
  • npm run {명명한 스크립트 이름} 명령어로 스크립트를 실행할 수 있다.
  • parcel build 명령어를 실행하면 번들링이 진행되어 index.html 파일이 압축되는 것을 볼 수 있다.

Babel과 Polyfilling

  • ES5 이전 JS만 지원하는 브라우저 등에서 모던 JS 코드를 정상적으로 동작하게 하려면 transpile과 polyfill이 필요하다고 배웠다.
  • parcel을 사용할 경우 Babel을 활용한 transpile 작업이 자동으로 진행된다.
  • 하지만 일부 feature의 경우 자동으로 변환되지 않는 코드가 있을 수 있다. 일반적으로 단순히 syntax에 관한 새로운 기능이면 변환이 잘 되지만(const -> var) find 메소드나 Promise와 같은 기능은 transpile이 불가능하다. 이러한 기능은 Polyfill로 해결해야한다.
import 'core-js/stable';
import 'core-js/stable/array/find';
import 'core-js/stable/promise';

// Polifilling async functions
import 'regenerator-runtime/runtime';
  • 위와 같은 패키지를 사용하면 Polyfill이 적용되어 변환되지 않은 코드도 정상적으로 동작한다.