npm package 개발 과정

wonder-lee·2023년 2월 5일
2

개발

목록 보기
1/3
post-thumbnail

개요

frontend 개발자들이 사용하게될 util 함수들을 package를 개발하고 배포하였던 과정의 포스트 입니다.

참여자 : 1명
기여도 : 100%
기술 : javascript, typescript, rollup.js
배운 점 : 
    - npm package 개발 과정
    - 공통 참여를 위한 package 개발 조직화 방법
    - javascript module system

예제

내용

배경

회사에서 운영중인 주요 service는 여러개의 service를 하나로 모아놓은 구
조입니다. 사용자 입장에서는 하나의 service로 보여지겠지만, 운영자 입장에서는 하나의 service가 아니라 여러개의 repository로 나누어져 있는 상태입니다.
이러한 배경 아래에서 service 전체에 동일하게 적용해야할 기능이 생길 때 마다 모든 repositroy에 code를 수정 혹은 추가해야하는 비효율적인 문제점이 자주 발생했습니다.

해당 문제점을 해결하기 위해서는 2가지 해결법이 보였습니다.
1. monorepo로 통일
2. 공통 기능 package 개발

결국에는 공수가 적으면서 안정성을 보장하는 package를 생성하기로 결정하였고, 해당 작업을 자원하면서 처음으로 npm package를 개발하게 되었습니다.

개발 과정

1. NPM 계정 및 organization 생성

npm package를 생성을 위해 npm 공식 homepage에서 계정을 생성하고, 회사의 frontend 개발자들과 같이 package를 관리하기 위하여 npm organization을 생성하였습니다.max-at 이라는 조직을 생성하면, 자동으로 @ scope가 생성됩니다.

2. folder 구조 설정

package의 전체 구조는 toss의 library 구조와 동일하게 설계하였습니다.
아래는 utils함수가 추가된 folder 구조입니다. packages라는 folder에 생성할 package를 추가해 나가면 됩니다.

├── README.md
└── packages
    └── utils // 라이브러리 명(@max-at/utils)
        ├── README.md
        ├── package.json
        ├── rollup.config.js
        ├── src
        │   ├── helpers // export되는 함수는 아니나 내부적으로 사용되는 함수를 생성하시면 됩니다.
        │   │   ├── factory // 내부적으로 사용하게 될 팩토리 함수를 생성하시면 됩니다.
        │   │   │   └── cookie.ts
        │   │   └── unit // 내부적으로 사용하게 될 단일 함수를 생성하시면 됩니다.
        │   │       ├── deleteCookiesByToken.ts
        │   │       ├── getDateTimeExpiresByToken.ts
        │   │       └── setCookiesByTokens.ts
        │   ├── index.ts // 최종적으로 export되는 함수들을 export 해주시면 됩니다.
        │   └── utils // 최종적으로 export되는 library의 기능을 file 단위로 생성하시면 됩니다.
        │       ├── deleteCookiesByToken.ts
        │       └── updateCookiesByToken.ts
        └── tsconfig.json
    └── new library...

3. package.json 설정

아래에서 생성하게 될 package 이름은 utils입니다.
위에서 생성한 repositoryd에서 packages 폴더 하위에 우리가 생성할 utils라는 folder를 생성합니다. 그 다음 생성한 utils folder로 들어와 npm init -y 명령어로 package의 기본 설정값으로 빠르게 package를 생성합니다. npm i 명령어를 통해, typescript, rollup.js 설치합니다.
package.json 세부 내용

4. typescript 설정

tsconfig.json file을 생성하여 typescript의 세부 설정을 합니다.
tsconfig.json 세부 내용

5. rollup.js 설정

5.1. rollup.js?

rollup.js는 library 제작 용도에 특화된 bundler 입니다. frontend 개발자라면 webpack을 아실 겁니다. rollup도 webpack과 비슷한 역할로 javascript의 bundler의 한 종류 입니다. rollup은 webpack과 다르게 build의 결과물을 ES6 module 형태로 추출할 수 있습니다.
ES6 module로 추출할 수 있다는 뜻은, module의 전부를 불러오는 것이 아닌, module 중에서 개발자가 필요한 기능만 import해서 사용할 수 있습니다. 이렇게 되면, code를 build하는 단계에서 treeshaking을 통해 사용하지 않는 code는 제거가 가능합니다. 또한, rollup library는 CJS, ESM으로 bundle이 가능합니다.

rollup.config.js file을 생성하여 bundle 세부 설정을 합니다.
rollup.config.js 세부 내용

6. package test

아마 위에 설정들의 세부 내용을 참고하여 초기 환경 설정을 마치게 되면 build와 publish는 아마도 정상적으로 실행이 될 겁니다. 그렇다면 우리가 package에 추가할 함수를 추가하면 어떻게 test를 하게 될까요?
저는 아래 3가지 과정의 test방법을 시도 했었고, 결론적으로는 symbol link를 이용한 test가 가장 유용합니다.

  1. 직접 배포 후 install
  2. local에서 경로를 통해 직접 install
  3. symbol link 이용

위에 방법 중 1번의 단점은 수정 후 매 번 build, publish, install의 단계가 필요했고, 2번의 단점은 수정 후 매 번 build, install의 단계가 필요했습니다.
하지만 symbol link를 이용하여 test할 경우에는 build, publish, install 단계가 모두 필요없이 수정된 source가 즉각적으로 install된 project에 반영되어 실시간으로 수정된 사항을 적용할 수 있었습니다!
아래는 symbol link를 이용하는 방법입니다.

###### symbol link 이용 시작 #####
# 1. package 경로 위치에서 아래 명령어를 실행하여, symbol link를 생성합니다.
# 1.1. 이 때 package.json에서 설정한 name으로 symbol link가 생성되어집니다.
sudo npm link

# 2. package를 test할 project 경로에서 아래 명령어를 실행하여 package를 연동합니다.
npm link @max-at/utils


###### symbol link 이용 종료 #####
# 1. package를 test한 project에서 아래 명령어를 실행하여 package를 제거합니다.
npm unlink --no-save @max-at/utils

# 2. package 경로에서 아래 명령어를 실행하여, symbol link를 제거합니다.
npm uninstall @max-at/utils

7. 배포 과정

작업한 package foloder의 package.json > version 을 0.0.1을 올리고 저장합니다.
작업한 라이브러리 폴더에서 npm publish 명령어를 실행하면 배포가 되어집니다.
만약 권한 에러가 발생할 경우 터미널에 npm login 명령어를 실행하여 npm이 로그인을 진행합니다.

오류

기록을 하지 못하였습니다. 😢

참고

profile
원더리입니다.

2개의 댓글

comment-user-thumbnail
2023년 2월 12일

곧 npm에 배포하게될 업무가 주어질 거 같은데 좋은 정보 감사합니다 ㅎㅎ

궁금한 것이 있는데...
Q1. rollup이 ES6 module 형태로 추출한다는 말씀이 ESM으로 번들링한다는 말과 같은 의미일까요?

Q2. cjs라면 트리쉐이킹이 왜 어려운가요?? 모듈 방식을 잘 몰라서 ㅜㅜ

답글 달기
comment-user-thumbnail
2023년 2월 12일

모노레포를 사용하면서 라이브러리도 추가해도 될 거 같은데, 지금은 라이브러리만 생성하신 건가요? 레포 관리는 어떻게 하시는지 궁금하네요.

답글 달기