TIL/2024

npm에 javascript library 올려보자

고무 오리 2025. 4. 24. 23:16
728x90
📢 Javascript 라이브러리를 NPM(node package manager)에 올려서 사용하고 싶어서 방법을 알아보고 올려봤어요

 

※ 24년 작성한 글 이에요

 

 

Javascript 라이브러리를 npm에 올려 CDN이나 package로 사용할 수 있어요

요즘 많이들 쓰는 Typescript로 라이브러리를 만들어봐요

 

 

⌨️ npm은 갑자기 왜?

npm 경험

프로젝트 진행 중 필요한 범용 기능 일부를 npm 라이브러리 형태로 호출하여 사용하고 싶었어요

Typescript

요즘 많이 쓰는 Typescript로 코드를 작성하여 npm에 올려봤어요

Type (.d.ts) 파일도 npm에 올려야해요

 

 

🤔 Javascript 라이브러리를 npm에 올리는 방법

1. 환경 설정

1) git 초기화

  • git init 또는 git clone 을 통해 초기화
  • .gitignore / readme.md / LICENSE 파일 들 생성

.gitignore

...
node_modules
dist
...

readme.md

...
![npm](https://img.shields.io/npm/v/[library_name])
![license](https://img.shields.io/npm/l/[library_name])
![downloads](https://img.shields.io/npm/dt/[library_name])
...

 

 

2) npm 초기화

  • npm init 통해 package.json 파일 생성
  • package.json은 git 기반으로 채워짐

 

 

3) Package 세팅

 

필요 패키지 설치

  • 다양한 브라우저 지원을 위한 babel
  • 코드 최적화를 위한 webpack
  • type 안정성 체크를 위한 typescript
  • 테스트를 위한 Jest
  • Development dependencies로 설치
npm install --save-dev @babel/cli @babel/core @babel/preset-env @babel/preset-typescript @types/jest babel-loader jest jest-environment-jsdom ts-jest ts-loader typescript webpack webpack-cli

 

 

패키지 별 설정 파일 작성

Babel 설정 파일(babel.config.json) 작성

더보기
{
  "presets": [
    ["@babel/preset-env", {
      // JavaScript 코드를 구형 브라우저 등에서 작동 가능하도록
		  // ES5나 ES6등의 하위 버전으로 Transpile 함
      "targets": "> 0.25%, not dead"
      // 전세계 사용자의 0.25% 이상이 사용하며
      // 최신 업데이트 지원되는 환경을 타겟으로 함
    }],
    "@babel/preset-typescript"
    // Typescript 코드를 javascript 코드로 변환하는 역할
    // TypeScript 컴파일러(tsc) 없이 빠르게 javascript 코드로 변환 가능
    // 단! Type Check는 안하니 타입 검사를 위해서는 tsc를 사용해줘야함
  ]
}

Webpack 설정 파일(webpack.config.js) 작성

더보기
const path = require('path');

module.exports = {
  mode: 'production',
  // Webpack의 실행 모드로 production이면 최적화된 빌드 생성
  // 난독화, 최적화, 압축 등의 작업 자동 수행
  entry: './src/index.ts',
  // Application의 진입점
  output: {
  // 번들링 결과물의 설정
    filename: 'index.js',
    // 번들링 된 파일 이름
    path: path.resolve(__dirname, 'dist'),
    // 번들 파일 생성 디렉토리
    library: 'ResponsiveImageMap',
    // UMD 형식 번들된 경우 노출 될 전역의 객체 이름
    libraryTarget: 'umd',
    // AMD(browser), CommonJS(Node), 전역 변수 모두에서 사용 가능한 포맷
    globalObject: 'this',
    // this로 해야 Node.js, 브라우저 환경 모두에서 제대로 동작
    umdNamedDefine: true
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: [
          'babel-loader',
          // 최신 JS(ES6+) 문법을 구형 브라우저에서도
          // 호환되도록 Transpile 함
          'ts-loader',
          // Typescript 컴파일하여 TypeCheck 및 JavaScript 변환
        ],
        exclude: /node_modules/,
        // bundling에서 제외할 경로
      },
    ],
  },
  resolve: {
    extensions: ['.ts', '.js']
  }
};

Typescript 컴파일 설정 파일(tsconfig.json) 작성

더보기
  • ts-loader 패키지가 참조하는 설정 파일
  • Babel과 함께 쓰일 때 ts-loader는 Type check만 하므로 target 등 일부 옵션은 사실상 필요 없긴함
{
  "compilerOptions": {
  // TypeScript 컴파일러가 코드 컴파일 시 적용할 옵션을 설정
    "target": "ES5",
    // 대부분의 구형 브라우저 지원, 사실상 안쓰임
    "module": "ESNext",
    // 최신 ECMAScript 모듈 시스템 사용, 사실상 안쓰임
    "moduleResolution": "node",
    "strict": true,
    // 엄격한 Type Check
    "esModuleInterop": true,
    "declaration": true,
    // type 파일(d.ts)을 생성 할지 여부 
    "skipLibCheck": true,
    // 외부 라이브러리의 타입 정의 파일(.d.ts) 검사 건너 뜀
    // 컴파일 속도 향상
    // 외부 라이브러리의 타입 오류로 인한 빌드 실패 방지
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist"
    // 결과물이 저장 될 경로 (type 파일 등..)
  },
  "include": ["src"]
  // TypeScript 컴파일러가 컴파일할 파일의 경로
}

Jest 설정 파일(jest.config.js) 작성

더보기
module.exports = {
  testEnvironment: 'jest-environment-jsdom',
  // browser 처럼 테스트 가능한 환경
  transform: {
    '^.+\\.ts$': 'ts-jest',
  },
  testMatch: ['**/tests/**/*.test.ts'],
  // test file들을 찾는 방법
};

패키지 설정 파일 (package.json) 수정

더보기
...
"main": "dist/index.js",
// 패키지의 진입점 파일
// 패키지 설치 및 사용 시 이 파일이 기본 로드
"types": "dist/index.d.ts",
// 다른 프로젝트에서 TypeScript 사용 시
// 해당 경로 타입 정의 파일 제공
"files": [
  "dist",
  "README.md",
  "LICENSE"
],
// NPM 배포 시 포함될 파일이나 디렉토리
"scripts": {
  "build": "webpack --config webpack.config.js",
  // build script
  "prepublishOnly": "npm run build",
  // npm 배포 전 실행 되는 스크립트
  "test": "jest --verbose"
  // Jest 테스트 실행 명령
},
...

 

2. 코드 작성 및 배포

코드 작성

폴더 구조는 아래와 같으며 소스 코드, 테스트 코드 작성

responsive-image-map/
├── dist/                  ← build 산출물 저장 위치
│   └── index.js
│   └── index.d.ts
├── src/                   ← 소스 파일 위치
│   └── index.ts
├── tests/                 ← Jest 테스트 파일 위치
│   └── index.test.js
├── .gitignore
├── README.md
├── babel.config.json      ← babel 설정
├── jest.config.js         ← Jest 설정
├── tsconfig.js            ← typescript compiler 설정
├── package.json           ← package 설정
└── webpack.config.js      ← webpack 설정

 

코드 작성 후 테스트 및 빌드 진행

npm test
npm build

 

 

npm 배포

npm 로그인 후 publish 진행

npm init
npm publish

배포를 github actions로 자동화 할 수도 있어요

 

 

3. 배포 후 라이브러리 사용

라이브러리 사용

npm install 또는 CDN으로 사용 가능

# Node Package Manager
npm install [library name]

# CDN
# Opting unpkg or jsdelivr
<script src="https://unpkg.com/[library name]/dist/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[library name]/dist/index.min.js"></script>

 

 

 

🙄 궁금증

Q1. @babel/preset-typescript ts-loader의 역할 중복 아닌가?

  • 중복으로 보일 수 있으나 각자의 역할이 다름
  • Babel의 빠른 빌드 성능을 활용하며 TypeScript의 타입 안전성 유지 가능

@babel/preset-typescript

  • ts 코드 js로 변환하는게 목적!
  • Type Check 없이 Transpile만 빠르게 진행

ts-loader

  • ts 코드 js로 컴파일 하며 Type Check 만 진행

 

 

🛍️ Takeaway

  • Javascript 라이브러리를 npm 등록하는 방법
  • Typescript 컴파일 설정 경험
  • Babel, Webpack, Jest를 통해 완성도 있는 라이브러리 만들기

 

 

 

728x90