간단한 NPM 라이브러리 배포해보기 2탄 (CLI 간단한 라이브러리 만들기 & 모든 환경 지원, ESM, CJS, TS)
간단 소개
- 당근 디자인시스템팀 프론트엔드 엔지니어 1년 6개월 째
- 디자인시스템 개발, 문서, 유지보수
- 롤업 플러그인, 피그마 플러그인, 스토리북 애드온 등 다양한 라이브러리 개발 및 배포 경험 (개수가 중요한 건 아니지만 최소 20개 이상?... 모노레포는 하나로 산정)
- 작년 해당 글로 발표 경험
- 시스템 업무 이외에도 웹 개발, 웹뷰 개발, 작게 나마 서버 개발도 같이 하고 있습니다.
- 점점 영향력을 키우고 싶어서 발버둥치고 있는 2-3년차 주니어 프론트엔드 엔지니어입니다.
개요
이전에 간단한 NPM 라이브러리 배포해보기 글에서는 간단한 라이브러리를 만들고 배포하는 방법에 대해 알아보았습니다. 해당 발표를 하고 1년이 지나고 다시 한번 발표 요청을 주셔서 내용 고칠 것이 있으면 고치고, 추가적으로 CLI 라이브러리를 만들어보는 내용을 추가하면 좋지 않을까 해서 이 글을 작성하게 되었습니다.
해당 내용은 발표 대본 용도로 작성된 글이라서 상세한 설명이 부족할 수 있습니다.
조금 더 적극적으로 참여하고 싶으시다면 해당 레파지토리 (npm-deploy-step-by-step)의 PR을 하나씩 확인하면서 직접 따라해보시는 것을 추천드립니다.
해당 글의 목표는 다음과 같습니다.
- ESM, CJS, TS를 모두 지원하는 라이브러리를 만들어보자.
- CLI를 간단하게 만들어보자.
ESM, CJS, TS를 모두 지원하는 라이브러리를 만들어보기
ESM vs CJS
해당 내용은 이전 글에서 상세하게 다뤘습니다.
핵심은 사용하는 측의 환경이 ESM 이라면 CJS, ESM 무엇이든 사용할 수 있지만 CJS 환경에서는 ESM을 사용할 수 없다는 것입니다.
Node 생태계에서 ESM이라는 새로운 기술이 나왔지만, CJS가 없어지는 것은 아니기 때문에 우리는 ESM, CJS 모두 지원하는 라이브러리를 만들어야 합니다. (더이상 지원하지 않는 것과 라이브러리 제공자가 지원해야 한다는 것은 다릅니다.)
CJS(CommonJS) vs ESM(ECMAScript Module)에 대해서는 이전 글에도 링크를 걸어두었지만 토스 블로그가 정리를 잘해놨습니다. 핵심만 꼽아보자면
- ES6 ECMAScript
2015
vs CommonJS by Mozilla engineer Kevin Dangoor in2009
. - ESM에서 CJS를 import 할 수는 있지만, CJS에서 ESM을 require 할 수는 없습니다. 왜냐하면 CJS는 Top-level Await을 지원하지 않기 때문입니다.
- ESM은 모듈간의 의존성을 정적으로 분석이 쉽기 때문에 (top-level exports) Tree Shaking이 용이합니다.
- CJS는 동적으로 모듈을 로딩할 수 있기 때문에 Tree Shaking이 어렵습니다. (정적 분석이 어렵기 때문입니다.)
- ESM은 import, export를 사용하고, CJS는 require, module.exports를 사용합니다.
- Server Side Rendering을 위한 Node 환경에서는 CJS를 사용합니다.
위와 같은 이유로 ESM, CJS 모두 지원하는 라이브러리를 만들어야 합니다. 어느 한 기술만 사용하는게 아니라 환경에 따라서 사용하는 모듈 시스템이 다릅니다.
하지만 이제 곧 CJS 환경에서도 ESM을
require()
할 수 있습니다.
STEP 1: 프로젝트 생성
프로젝트 생성
1yarn init -y
- 린터 설정
- .gitignore
(실습)
STEP 2: CJS만 지원하는 라이브러리 만들어보기
CJS으로 라이브러리를 배포해보고 ESM, CJS 환경에서 사용해보고 차이점 느껴보기: 라이브 코딩 (이전 포스트 참고)
- src/index.js 작성하기
0.0.0-onlyCJS
로 배포하기- esm, cjs에서 테스트 해보기
- 전부 잘 되는거 확인하기
(실습)
STEP 3: ESM으로 라이브러리를 배포해보고 차이점 느끼기
ESM으로 라이브러리를 배포해보고 ESM, CJS 환경에서 사용해보고 차이점 느껴보기: 라이브 코딩 (이전 포스트 참고)
type: module
, src/index.js ESM으로 변경0.0.0-onlyESM
로 배포하기- esm, cjs에서 테스트 해보기
- cjs에서 안되는 거 확인하기
(실습)
요기까지는 방대한 Node 환경에서 ESM, CJS 모두 지원해야 하는 명분에 대해서 알아보았습니다. 그럼 오픈소스 개발자는 항상 ESM, CJS 코드를 작성해야 하는걸까요? 그렇지 않습니다. 오픈소스 개발자는 단 하나의 코드를 작성하고 빌드 과정을 통해서 ESM, CJS 모두 지원하는 라이브러리를 만들어야 합니다.