안녕하세요! 무스마 FE파트의 Yong입니다.

입사 후 온보딩으로 npm 배포를 실습해 보며 정리한 것들을 바탕으로 가이드를 작성해 보려 합니다.

여담이지만 저는 입사 전 npm에 배포되어 있는 패키지들을 사용할 줄만 알았지 배포해 본 경험은 없었습니다.. 반면, 무스마에서는 패키지가 잘 관리되고 있어서 무스마 크루들의 노력이 대단하다고 느꼈습니다!

목차

사전 준비

  • Node 및 npm 설치
  • npm 계정
  • npm에서 Organization(조직) 생성 이 가이드에서는 scoped packages로 배포할 예정입니다. (@<조직 이름>/<패키지 이름>)
  • TypeScript + React/Vue 기초 지식

프로젝트 생성하기

폴더 생성

두 가지 폴더를 생성하겠습니다. 하나는 패키지 폴더이고 또 다른 하나는 패키지를 테스트하는 폴더입니다.

저는 utils와 playground 폴더를 생성하였습니다.

(Github은 선택사항으로 두겠습니다)

package.json 생성

package.json을 생성하도록 하겠습니다.

$ npm init --scope=<조직-이름>

  • --scope 옵션으로 패키지 이름 앞에 조직 이름을 붙일 수 있습니다. 예를 들어 npm 패키지 설치 시 다음과 같은 명령어로 설치 가능합니다.

$ npm install @<조직 이름>/<패키지 이름>

저는 여기서 musma-test으로 스코프를 지정하겠습니다.

$ npm init --scope=musma-test

package name: (@musma-test/utils)
version: (1.0.0)
description: JS utils for everyone
entry point: (index.js)
test command:
git repository:
keywords: musma
author: yong
license: (ISC)
{
  "name": "@musma-test/utils",
  "version": "1.0.0",
  "description": "JS utils for everyone",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": ["musma"],
  "author": "yong",
  "license": "ISC"
}

module 작성

index.js 파일을 생성 후 간단한 함수를 작성하고 CJS로 모듈을 작성했습니다.

image

테스트하기

npm에 배포하기 전에 작성한 모듈을 로컬 환경에서 테스트 할 수 있습니다.

가장 쉬운 방법은 npm link를 사용하는 방법입니다. utils폴더 안에서 npm link를 명령어를 실행시키면 npm이 해당 폴더에 링크를 생성해주고 다른 폴더에서 링크된 패키지를 사용할 수 있도록 해줍니다.

$ npm link

아래 명령어로 현재 전영범위에 설치된 npm 패키지들을 확일 할 수 있습니다.

$ npm ls -g --depth=0

image

다음, 위에서 만들었던 playground 폴더에서 utils 패키지를 테스트 하기위해 명령어로 패키지를 설치합니다.

$ npm link @musma-test/utils

playground 폴더 내부에 node_module 폴더가 생성된 것을 확인할 수 있습니다.

image

playground 프로젝트에서 index.js 파일을 생성하고 아래와 같이 작성하고 실행시켜 보도록 하겠습니다.

image

$ node index.js

image

정상적으로 실행된 것을 확인할 수 있습니다. 패키지를 만들고 로컬에서 테스트하였으니 다음으로 npm에 배포해 보도록 하겠습니다.

배포하기

먼저 터미널 창에서 npm에 로그인하도록 합시다.

$ npm login

다음으로 배포를 하겠습니다. 패키지 이름에 네임스페이스(e.g. @musma-test)를 추가하면 패키지가 기본값으로 private으로 배포가 되기 때문에 --access=public으로 옵션을 주어서 public 패키지임을 명시해주어야합니다. (private은 유료입니다!)

$ npm publish --access=public

image

npm에 배포까지 정상적으로 마무리된 것을 확인할 수 있습니다.

image

TypeScript는 안되나요?

현재 무스마의 FE 팀에서는 TypeScript를 사용하고 있습니다. 그러므로 React+TypeScript 프로젝트를 하나 생성해서 @musma-test/utils 라이브러리를 사용해보겠습니다.

리액트 프로젝트를 하나 생성해서 @musma-test/utils 패키지 설치 후 라이브러리를 사용하려고 했지만 편집기에서 TS 에러가 발생하는 것을 볼 수 있습니다.

image

이 오류는 TypeScript가 모듈에 대한 타입 선언 파일(.d.ts)을 찾지 못하기 때문에 발생합니다.

앞서 만든 패키지가 타입을 지원하도록 하기 위해서 utils를 수정하도록 하겠습니다.

먼저 typescript 패키지를 설치합니다.

$ npm i typescript -D

그리고 tsconfig.json 파일을 추가해 주도록 합니다.

  • module은 CJS 그대로 진행하겠습니다.
  • declaration을 true로 설정해야 .d.ts 파일이 자동으로 생성되게 됩니다.
  • ‘outDir’와 ‘include’경로를 설정해주도록 합시다.
{
  "compilerOptions": {
    "target": "ES6",
    "module": "CommonJS",
    "esModuleInterop": true,
    "declaration": true,
    "strict": true,
    "outDir": "dist"
  },
  "include": ["src/index.ts"]
}

index.js 파일을 src폴더 내부로 이동시켜주고 index.ts로 수정하고 코드를 수정해줍니다.

image

이제 컴파일 해보도록 하겠습니다.

$ tsc

dist 폴더 안에 Index.ts 와 index.d.ts 파일이 생성된 것을 알 수 있습니다.

image

마지막으로 package.json을 수정하고 배포하도록 합니다.

{
  "name": "@musma-test/utils",
  "version": "1.0.1" /* 버전 수정 */,
  "description": "JS utils for everyone",
  "main": "dist/index.js" /* main 파일 수정 */,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "exports": {
    ".": {
      "types": "./dist/index.d.ts" /* type 참조 파일 */
    }
  },
  "keywords": ["musma"],
  "author": "yong",
  "license": "ISC",
  "devDependencies": {
    "typescript": "^5.2.2"
  }
}

$ npm publish --access=public

배포된 패키지를 다시 리액트 프로젝트에 설치한다면 이전에 발생했던 타입 에러가 사라지는 것을 알 수 있습니다.

마무리

모듈을 npm에 배포하는 것과 타입 스크립트를 적용까지 정리해 보았습니다. npm에 직접 배포해 보기 전까지는 어려운 작업일 거라고 생각했지만, 막상 직접 배포해 보니 크게 어렵지 않았습니다.

다음에는 모노레포를 구성해서 패키지들을 관리하는 방법에 대해서 작성해 보려 합니다.

읽어주셔서 감사합니다.