NPM Publish A to Z (feat. Channel Web SDK Loader)

고객용 메신저(Web SDK) 설치 스크립트를 NPM 패키지로 배포하는 과정

Channel Talk

  • 테크 인사이트

안녕하세요😊 채널톡 엔지니어 제프입니다. 이번 글에서는 고객용 메신저(Web SDK) 설치 스크립트NPM 패키지로 배포하는 과정을 공유하려고 합니다.


1. NPM 패키지 기본 설정

1-1. package.json 파일 생성하기

  • package.json 파일을 통해 사용자들이 패키지 정보를 확인하고 쉽게 설치할 수 있습니다.

  • NPM registry에 배포된 패키지는 package.json 파일을 포함해야 합니다.

  • npm init command를 사용해서 기본 정보가 입력된 package.json을 생성할 수 있습니다.

  • 생성된 package.json을 바탕으로 나머지 세부 설정을 진행합니다.

1-2. 세부 설정 진행하기

name (required)

"name": "@channel.io/channel-web-sdk-loader"

  • 패키지 이름입니다.

  • 소문자와 한 단어로 구성해야 하며, hyphen(-)과 underscore(_)를 포함할 수 있습니다.

  • scope를 prefix로 사용할 수 있습니다 (e.g. @channel.io)

  • what is scope?

    • NPM user와 organization은 고유의 scope를 소유합니다.

    • 권한이 없는 사람들은 scope에 package를 추가할 수 없습니다.

    • scope는 organization의 official package를 나타낼 수 있는 좋은 방법입니다.

version (required)

"version": "1.1.2"

  • x.x.x 형식이며 semantic versioning guidelines을 지켜야 합니다.

    • 패키지 배포 시 breaking point가 있다면, Major release를 진행합니다.

    • 이전 버전과 호환가능한 새로운 feature 배포라면, Minor release를 진행합니다.

    • 이전 버전과 호환가능한 bugfix 배포라면, Patch release를 진행합니다.

description

"description": "Official Channel Web SDK Loader"

  • 패키지에 대한 설명입니다.

  • 사람들이 패키지를 검색할 때 도와줍니다.

license

"license": "Apache-2.0"

  • 패키지 사용 시 허가 사항들과 제한 사항들을 표시합니다.

  • 일반적으로 OSI에서 승인한 라이센스 사용을 권장합니다.

  • 라이선스에 명시된 의무사항들은 실제 소스코드가 배포될 때 효력이 발생합니다.

대표적인 license

  • MIT License:

    • 권한 : 상업적 사용, 배포, 수정, 비공개로 사용가능

    • 사용조건: 저작권 및 라이선스 고지

    • 제한사항: 해당 라이선스 오픈소스를 사용하거나 기타 거래 시 발생하는 모든 청구, 손해 또는 기타 책임에 대해 책임을 지지 않습니다.

    • NPM package에서 가장 많이 사용되는 license입니다.

  • Apache License 2.0:

    • 권한: 상업적 사용, 수정, 배포, 사용이 자유롭고 특허권 부여 및 비공개 사용 가능.

    • 사용조건: 저작권 및 라이선스 고지, 변경사항이 있었다면 문서화 요구됨.

    • 제한사항: 보증을 면제하고 책임을 제한. 상표권 사용을 제한합니다.

    • Spring Boot 등의 오픈소스에서 사용하는 라이선스입니다.

  • GPL v3.0

    • 권한: 상업적 사용, 수정, 배포, 사용이 자유롭고 특허권 부여 및 비공개 사용 가능.

    • 사용조건: 저작권 및 라이선스 고지, 변경사항 문서화. 소스코드 공개 (copyleft)

    • 제한사항: 보증을 면제하고 책임을 제한.

    • GNU 소프트웨어에서 사용하는 라이선스입니다.


2. ESM, CommonJS(CJS) 모두 지원하기

  • ESM은 정적분석이 쉽기 때문에, tree shaking이 용이합니다.

  • CJS 모듈 시스템에서는 ESM이 호환되지 않습니다.

  • 따라서 CommonJSES module imports 모두 지원하는 Conditional Exports를 사용합니다.

2-1. Conditional Exports

JSON
  • exports 필드 사용 시, 같은 import path에 대해 특정 조건에 따라 다른 모듈을 제공할 수 있습니다.

    • (e.g.) load 방식(require(), import)에 따라 다른 모듈을 지원할 수 있습니다.

  • Node.js 12 부터 지원합니다.

exports field

  • exports field는 "."으로 시작하는 상대 경로로 작성합니다.

  • load 방식에 따라 Node.js와 Typescript가 바라볼 entry 파일을 명시합니다.

  • ESM 파일 확장자로 .mjs.mts를 사용합니다.

    • type필드가 없다면, Node.js는 해당 package.json이 가장 가까운 부모인 모든 .js에 대해 CommonJS module format을 사용합니다.

    • type필드의 값에 관계없이 .mjs 파일은 항상 ES Module로 처리되고 .cjs 파일은 항상 CommonJS로 처리됩니다.

    • 즉 위 설정에서 ESM import path와 매핑시킬 파일에 .mjs 확장자를 사용해야 해당 파일이 ES Module로 처리합니다.

2-2. main, module, types (legacy support)

JSON
  • older version TS, Node.js를 위한 fall-back 설정입니다.

main

  • Node.js 12보다 오래된 버전을 위한 CJS fall-back용 파일을 설정합니다

module

  • Node.js12보다 오래된 버전을 위한 ESM fall-back용 파일을 설정합니다

types

  • TypeScript 4.7보다 오래된 버전을 위한 fall-back용 파일을 설정합니다.


3. side effect free 설정하기

JSON
  • "side Effect"는 import될때, export 외에 다른 특별한 동작을 수행하는 코드를 의미합니다.(e.g. polyfill)

  • "sideEffects" = false설정 시, webpack compiler에게 현재 패키지가 순수하다는 힌트가 제공됩니다.

  • 패키지가 순수할 경우, webpack은 해당 패키지의 unused exports를 안전하게 제거할 수 있습니다.(tree shaking수행)


4. TypeScript 설정

tsconfig 파일을 생성하고 세부 설정을 진행합니다.

4-1. tsconfig 파일 생성하기

  • tsc -init command를 사용해서 기본 설정이 담긴 tsconfig 파일을 생성합니다.

  • 생성된 tsconfig를 바탕으로 세부 설정을 진행합니다.

4-2. Compile Options 설정하기

TypeScript 작동 방식을 설정합니다.

JSON

target

  • emit되는 .js 파일의 JavaScript version 및 호환가능한 lib를 설정합니다.

  • 최신 브라우저들은 모두 ES6 features를 지원합니다.

  • 현재 패키지는 tsc -init 기본 설정인 es2016을 그대로 사용합니다.

  • Object.entries array.at 같은 lib 사용을 위해선 보다 높은 target 설정이 필요합니다.

module

  • 프로그램의 모듈 시스템을 설정합니다.

  • ESM, CJS로 설정된 tsconfig를 사용해서 각각 컴파일을 수행합니다.

    • ES Module: "module": "ESNext"로 설정된 tsconfig을 사용해서 컴파일합니다.

    • CommonJS: "module": "CommonJS"로 설정된 tsconfig을 사용해서 컴파일합니다.

outDir

  • .js, .d.ts파일이 emit되는 경로를 지정합니다.

  • outDir 필드를 설정하지 않으면, .ts 파일과 동일한 디렉토리 경로로 .js파일이 emit 됩니다.

declaration

  • 프로젝트 내 모든 JS, TS파일에 대한 .d.ts 파일 생성 여부를 설정합니다.

  • .d.ts파일은 모듈의 external API를 설명하는 type definition 파일입니다.

  • TypeScript는 d.ts파일을 통해 intellisense 및 정확한 타입을 제공할 수 있습니다.

4-3. include 설정하기

프로그램에 포함할 filenames 또는 patterns의 배열을 명시합니다.

JSON

5. API References 문서 자동 생성하기

  • TypeDoc을 사용합니다.

  • TypeDoc은 TypeScript를 위한 documentation generator 입니다.

  • TypeScript 소스 파일에 포함된 주석을 구문 분석하여 코드를 설명하는 정적 사이트를 생성합니다.

  • Github Pages를 사용해 API 문서를 손쉽게 배포할 수 있습니다.

  • 패키지 릴리즈 시 API 문서도 같이 배포되도록 CI/CD를 구성하면 항상 최신 문서를 사용자에게 제공할 수 있습니다.

    • Github Actions를 사용해 CI/CD를 구성합니다.

    • actions-gh-pages 을 활용해서 gh-page publish workflow를 간단히 구현할 수 있습니다.


6. Local 환경 패키지 테스트

Plaintext
cd ~/projects/channel-web-sdk-loader        # go into the package directory  
npm link                                    # creates global link  
cd ~/projects/page-for-test-sdk             # go into some other package directory.  
npm link @channel.io/channel-web-sdk-loader # link-install the package  
  • NPM Publish 전 로컬 환경에서 패키지를 테스트합니다.

  • npm link를 사용해서 손쉽게 로컬 테스트를 진행할 수 있습니다.

    1. package 경로에서 npm link command를 실행합니다.

    2. 전역 폴더에 npm link command가 실행된 패키지로 연결되는 symbolic link가 생성됩니다.

    3. 다른 폴더 경로에서 npm link package-name command를 실행합니다.

    4. 전역에 설치된 package-name에서 현재 폴더의 node_modules/로 연결되는 심볼릭 링크가 생성됩니다.

    5. 테스트 완료 후 npm uninstall -g package-name command를 실행해 전역에 설치된 symlink를 제거합니다.


7. NPM Registry에 패키지 배포하기

7-1. Public Packages vs Private Packages

7-2. publish 관련 package.json 설정

files

JSON
  • 패키지가 dependency로 설치될 때 포함할 항목들을 나열한 file patterns 배열입니다.

  • 아래 파일들은 설정에 상관없이, 항상 포함됩니다

    • package.json

    • README

    • LICENSE / LICENCE

    • The file in the main field

    • The file(s) in the bin field

Life Cycle Scripts > prepublishOnly

JSON
  • prepublishOnly 스크립트를 사용하면 npm publish 전에 build를 실행할 수 있습니다.

7-3. Github Release 시 NPM Publish 수행하기

Plaintext
// release.yml
  steps:
    - name: Publish to NPM
      run: npm publish
      env:
        NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Plaintext
// .npmrc
//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}

8. 사람들에게 알리기

8-1. SEO

package.json에 keywords 추가하기

  • keywords를 통해 사람들이 npm search에 나열된 패키지를 찾을 수 있습니다.

JSON

GitHub에 topics 추가하기

  • GitHub Topics을 통해 사람들이 topic으로 패키지를 찾을 수 있습니다.

8-2. 개발자 문서

8-3. Release Notes

8-4. Newsletters

  • 제품팀에서 운영하는 개발자 뉴스레터(월간채널)에 Web SDK NPM 패키지를 소개합니다.

8-5. 팀 내 공유 및 발표

  • NPM 패키지 릴리즈를 팀 내 공유하고, 릴리즈 과정에 대해 테크톡 발표를 진행합니다.


지금까지 NPM 패키지 배포의 전반적인 과정을 살펴봤습니다. 패키지 배포는 코드 작성, 버전 관리, 라이선스, 모듈 시스템, 문서작업, 그리고 사람들에게 알리는 작업까지 많은 부분 고려가 필요하다고 생각합니다. NPM 배포 방법을 찾고 계신 분들에게 이 글이 도움이 되면 좋겠습니다. 감사합니다!

[이런 글도 추천드려요]

We Make a Future Classic Product

채널팀과 함께 성장하고 싶은 분을 기다립니다

사이트에 무료로 채널톡을 붙이세요.

써보면서 이해하는게 가장 빠릅니다

회사 이메일을 입력해주세요