채용 우대사항에 빠지지 않고 보이는 Webpack, Babel 사용이 능숙한 분. CRA를 사용해 프로젝트를 진행해 왔었기에, JS 신문법을 이전 버전의 문법으로 번역해준다거나 (Babel), 모듈로 이루어진 파일들을 압축해준다(Webpack) 정도로만 어렴풋이 알고있었다. 이들을 확실히 이해하고 스스로 활용할 수 있게 하기 위해 정리해 놓으려 한다.
Webpack
웹팩이란
웹팩(Webpack)은 모던 자바스크립트 (ES6+) 애플리케이션을 위한 모듈 번들러이다. 모듈이란 특정 기능을 갖는 작은 코드 단위를 의미한다. 함수나 컴포넌트가 담겨 있는 js파일부터, 이미지, 동영상 등을 모두 포괄하는 개념이다. 이 자원들을 하나의 파일로 병합, 압축하는 과정을 번들링이라고 한다.
기존 모듈의 문제점과 표준화
자바스크립트가 등장한 초기에는 HTML 파일에서 바로 <sciprt> 태그를 이용해 모듈들을 관리할 수 있었지만, 시대가 발전하며 서비스의 규모가 커지고 코드가 복잡해지면서 모듈화에 대한 필요성이 생기게 되었다.
변수 스코프 문제
자바스크립트는 변수를 선언하면 파일마다 독립적인 스코프를 갖는 것이 아닌, 하나의 전역 객체를 공유한다. 이게 코드 짤 때는 편하지만, 여러 개의 <script>를 불러와 적용하면 충돌이 발생하게 되고, 제일 마지막에 선언 혹은 할당한 값으로 덮어씌워지게 된다. 이러한 문제를 해결하기 위해 다양한 라이브러리들이 등장하였다.
CommonJS
exports 키워드로 모듈을 만들고, require() 함수로 임포트하는 방식으로 제작된 모듈화 라이브러리이다. CommonJS를 이용해 전역변수와 지역변수를 분리하여 독립적인 스코프를 가질 수 있고, 파일을 통째로 import하는 것이 아닌 필요한 함수나 변수만 가져올 수 있다. 또한 브라우저 뿐만 아니라 Server-side 애플리케이션 등의 환경에서도 사용이 가능하지만, 필요한 모듈을 모두 내려받을 때까지 아무것도 할 수 없다는 단점이 존재한다.
AMD (Asynchronous Module Definition)
네트워크를 통해 비동기 환경에서 모듈을 사용할 수 있는 라이브러리이다. CommonJS와 AMD를 통함한 방식을 UMD라 한다.
ES6
모던 자바스크립트에 들어서면서, Import와 Export 문법을 통한 모듈화 방식이 추가되었고 이를 표준화하여 사용 중이다.
주요 개념
Entry
웹팩에서 웹 자원을 변환하기 위한 최초 진입점으로, 자바스크립트 파일의 경로를 값으로 갖는다. 이 진입점으로부터 재귀적으로 의존적인 모듈을 찾기 시작한다. Entry가 여러 개 필요한 경우 배열 형식이나 객체 형식으로 추가가 가능하며, 이를 다중 엔트리 포인트라고 한다.
// webpack.config.js
module.exports = {
entry: './src/index.js'
}
index.js를 엔트리 포인트로 지정해주었다. 해당 파일에는 애플리케이션의 전반적인 구조와 이를 동작할 수 있는 내용이 담겨 있어야 한다.
Output
웹팩의 결과물을 저장할 파일 경로를 의미한다. 또한 filename 또는 path 속성을 추가적으로 정의해준다.
// webpack.config.js
module.exports = {
output: {
filename: 'bundle.js'
}
}
Loader
애플리케이션 해석 간 스크립트 파일이 아닌 자원 (HTML, CSS, Images, Font) 등을 변환할 수 있게 해주는 속성이다. 패키지 매니저를 통해 추가적인 하위 로더를 설치하고, 정규식을 이용해 로더에 적용할 파일을 필터링할 수 있다. 자주 사용되는 로더는 CSS, Babel, Sass, File, Vue, TS Loader 등이 있다.
Plugin
압축된 결과물의 형태를 바꿀 수 있는 속성이다. 웹팩의 빌드 진행률을 표시해주거나, 결과물을 HTML 파일로 생성하는 등의 제어가 가능하다.
Babel
Compile
바벨은 ES6 코드를 이전 버전과 호환되는 문법으로 변환하는 데 사용하는 소스 대 소스 컴파일러 (transpiler)이다. 받아온 파일을 통째로 번역하는 것이다. 최신 기술의 동향은 빠르게 변화하고 있고 브라우저의 지원이 이를 발맞추어 따라갈 수 없기에, 혹은 아직 많은 사람들이 구버젼의 브라우저를 사용하고 있기에, Babel은 필수적이다.
// Babel Input: ES2015 arrow function
[1, 2, 3].map(n => n + 1);
// Babel Output: ES5 equivalent
[1, 2, 3].map(function(n) {
return n + 1;
});
이 외에도 추가적인 하위 패키지 설치를 통해 JSX, TSX 유형의 스크립트 파일도 변환할 수 있다.
Polyfill
Babel은 문법을 변환하는 역할을 할 뿐이다. 사용자가 작성한 코드에 있는 신문법의 메서드나 속성들은 추가적으로 프리셋을 설정해주어야 하는데, 이를 처리해주는 것이 Polyfill이다. 바벨은 컴파일 간, 폴리필은 런타임 환경에서 실행된다.