TypeScript 와 SMS client를 NPM 모듈로 만들어서 배포하기 (node-sens)

bumkeyy·2020년 8월 6일
17
post-thumbnail

🤗 이 글에는 욕설이 없습니다. 누구나 읽을 수 있는 안전한 글입니다.

안녕하세요:)
다들 npm 모듈 하나씩은 만들고 배포해보셨나요?

항상 해봐야지 하고 생각만 하고 있던 찰나에 사이드 프로젝트를 진행하면서 있었으면 좋겠다 싶은 client를 npm 모듈로 만들어봤습니다.

코드나 과정은 간단하지만, 제가 그랬고, 누구나 그렇듯 후기를 남기면 많은 분들께 도움이 되고 motivation도 되는 것 같아서 후기를 한번 써볼려고 합니다 ㅎㅎ

그럼 시작할게요!

🤔 어떤걸 npm 모듈로 만들죠?

연초에 친구와 함께 push 관련된 앱을 개발하는 프로젝트에서 벡엔드 개발을 맡아 진행했어요. 그중 회원가입에 필요한 인증을 SMS로 정하게 되었고, SMS에 사용할 수 있는 플랫폼이나 모듈을 리서치하고 있었습니다. (nodejs를 기반으로 만들었어요 ㅎ)

가장 유명한 twilio도 있었지만, Naver Cloud Platform(이하 NCP)에서 SMS 관련 서비스를 괜찮은 가격에 제공하는걸 알게 됬습니다.

Simple & Easy Notification Service 라는 이름에 서비스였고(이하 sens), 테스팅하기에 가격도 괜찮고 속도도 나쁘지 않은 것 같아 한번 써보기로 했습니다.

NCP에서는 open api 문서를 제공했고, 그 api 문서를 보고 사용을 하는 방식이였습니다.

물론 저는 npm부터 검색을 했고, 누군간 만들었겠지 했는데 아직 홍보가 안되서 그런지 자료가 별로 없더라구요...

블로그에서 사용한 후기는 있지만, 이참에 npm 모듈로 만들어서 편리하게 사용해보도록 결심했습니다!

🚀 Project 시작하기

먼저 github 레포부터 만들었어요. sens라는 이름을 쓰고 싶었는데 npm에 이미 7년전에 누군가 만들어놔서... node-sens로 정하고 readme 부터 만들었습니다!

‼️ npm에서 이름 중복은 허용이 안되요!

배포가 목적이였기 때문에 제일 먼저 package.json 부터 정성스럽게 만들었습니다 😀

$ npm init
...

언어는 typescript로 개발하기 위해 typescript 또한 설치합니다.

$ npm typescript --save-dev

package.json에는 maintypes를 추가해줍니다!

#! package.json
{
  ...
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  ...
}

open api를 사용하기 때문에 request에 필요한 axioscrypto를 설치합니다.

$ npm install axios crypto --save

tsconfig.json 파일도 생성합니다.

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "declaration": true,
    "outDir": "dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["./src/**/*"],
  "exclude": ["./src/__test__"]
}

src 디렉토리까지 root 위치에 만들면서 기본 골격을 완성했습니다!

🏃‍ 클라이언트 개발하기

먼저 골격은 src 내에 index.ts를 만들고, ncp_client.ts를 불러오는 형식으로 모듈을 만들었어요.

index.ts는 이렇게 만들었고,

#! index.ts
export { NCPClient } from './ncp_client';

ncp_client.ts는 이렇게 사용했습니다.(자세한 코드는 github에 있습니다!)

#! ncp_client.ts

import axios from 'axios';
import crypto from 'crypto';

export type NCPClientOptions = {
  phoneNumber: string;
  serviceId: string;
  secretKey: string;
  accessKey: string;
};

...

export class NCPClient {
  ...
}

README.md 에서 볼 수 있듯이, 아래처럼 간단한 정보만 알면 다른 건 신경 쓸 필요 없이 바로 SMS 서비스를 이용할 수 있어요!

import { NCPClient } from 'node-sens';

const ncp = new NCPClient({
  phoneNumber: '000-0000-0000',
  serviceId: 'serviceId',
  secretKey: 'secretKey',
  accessKey: 'accessKey',
});

const { success, msg, status } = await ncp.sendSMS({
  to: '000-0000-0000',
  content: 'Hello SENS',
});

🐞 테스트 적용하기

많은 사람이 사용하도록 만든 모듈일수록 테스트가 정말 중요하다고 생각합니다. 여기선 jest를 사용합니다.

$ npm i jest ts-jest @types/jest --save-dev

package.json에 관련 설정도 추가합니다.

#! package.json

{
  "scripts":{
    "test": "jest",
    ...
  }
   ...
   "jest": {
    "transform": {
      "^.+\\.ts$": "ts-jest"
    },
    "testRegex": "\\.test\\.ts$",
    "moduleFileExtensions": [
      "ts",
    ],
    "globals": {
      "ts-jest": {
        "diagnostics": true
      }
    }
  },
  ...
}

src 디렉토리 내에 __test__ 디렉토리를 생성하고 test 파일을 만듭니다.

테스트 파일에서는 axios 모듈을 mocking해서 request를 날리지 않아도 테스트가 가능하도록 구현합니다.

const axios = require('axios');
import { NCPClient } from '../ncp_client';

jest.mock('axios');

...

describe('NCP Client', () => {
  let ncp: NCPClient;

  beforeEach(() => axios.mockClear());

  beforeAll(() => {
  ...
  });

  test('send SMS success', async () => {
    axios.mockImplementationOnce(() =>
      Promise.resolve({
        status: 202,
        statusText: 'Accepted',
      })
    );
    const { success, msg, status } = await ncp.sendSMS({
      to,
      content,
    });
    expect(success).toBe(true);
    expect(msg).toBe('Accepted');
    expect(status).toBe(202);
  });
  ...
});

🛠 Travis CI 적용하기

travis ci는 오픈소스를 대상으로 무료로 해주는 툴로 github에 있는 레포를 바로 적용할 수 있어요.

travis ci에 로그인하고 해당 github 레포를 연동합니다. 그리고 root 위치에 travis ci 설정을 위한 .travis.yml 도 생성합니다.

#! .travis.yml

language: node_js
node_js:
  - stable
install:
  - npm install
script:
  - npm test

이제 push가 될때 마다 자동으로 npm test를 돌려서 빌드를 확인해줍니다!

📦 NPM publish 하기

먼저 npm에 가입되어 있어야 하고 local console에서 npm registry에 로그인을 해야합니다.

console에서 npm login을 통해 로그인을 합니다.

배포를 하기전에 로컬에 있는 환경이 그대로 push 되기 때문에 불필요한 파일은 설정에서 빼야합니다. root 위치에 .npmignore 파일을 생성합니다.

#! .npmignore
src
coverage
.vscode
.travis.yml
LICENSE
__test__
tsconfig.json

이제 npm run build를 통해 dist 디렉토리에 컴파일된 파일을 생성하고, npm run publish를 통해 배포할 수 있습니다.

$ npm run build
$ npm run publish

👏 마무리

말로하면 쉽지만 개발하면서 블로그도 많이 찾아보고, 실수도 많이 했습니다. 그래도 npm에 올라간 모듈을 보니까 뿌듯하더라구요 ㅎㅎㅎ

npm에 관심이 있거나 만들고 싶은 모듈이 있다면 꼭 해보세요!

github 주소 : https://github.com/Bumkeyy/node-sens
npm : https://www.npmjs.com/package/node-sens

질문이나 오타 혹은 잘못된 내용이 있다면 언제든 환영합니다 😁

profile
안녕하세요 :)

8개의 댓글

comment-user-thumbnail
2020년 8월 12일

안녕하세요. 글 잘 봤습니다. 저걸 node.js 서버에 넣어서 인증번호 인증 구현을 하고싶고
클라이언트에서 어떤 url로 포스트 요청을 했을때 인증번호 보내고 받아 체크하고 싶은데 잘 안되네요 ㅠㅠ
혹시 도와주실수있을까요...

1개의 답글
comment-user-thumbnail
2020년 8월 12일

+추가 댓글
success, msg, status 로 값 반환이 undefined 로 나오네요 ㅠㅠ
console.log (success, msg, status) 했을때 아무값이 안나오는데 어떤 문제가 있는 걸까요?

1개의 답글
comment-user-thumbnail
2020년 9월 22일

안녕하세요, 저도 만드신 패키지로 회원가입 문자인증 구현 중에 있습니다! 그런데 문제가 생겨 질문 좀 드리려 하는데요. 우선 SENS 발신번호를 제 번호로 했고 제 폰에는 문자 수신이 잘 됩니다. 그런데 다른 번호에 API를 통해 보내게 되면 SENS 가 동작하지 않고 있습니다.. ㅠ 혹시 네이버 클라우드 플랫폼에서 무언가를 설정해주어야 할까요?

1개의 답글