migration2025-05-11·8·73/348

npm deprecated 패키지 대체 방법 완벽 가이드

npm에서 deprecated된 패키지를 발견했을 때 적절한 대체 패키지를 찾고 마이그레이션하는 방법을 다룹니다.

Introduction

npm 프로젝트를 개발하다 보면 deprecated된 패키지를 사용하고 있는 경우가 많습니다. 이러한 패키지는 보안 취약점이 있거나 더 이상 유지보수되지 않을 수 있어 적절한 대체 패키지로 마이그레이션이 필요합니다.

Environment

# deprecated 패키지 확인
npm list --depth=0 2>&1 | grep -i warn

# npm audit로 보안 검사
npm audit

# deprecated 패키지 상세 확인
npm info request deprecated
# "request has been deprecated, see https://github.com/request/request/issues/3142"

Problem

다음과 같은 deprecated 패키지들이 발견되었습니다:

# npm install 후 경고 메시지
npm WARN deprecated request@2.88.2: request has been deprecated
npm WARN deprecated multer@1.4.5-lts.1: Multer is unmaintained
npm WARN deprecated node-uuid@1.4.8: Use uuid module instead
npm WARN deprecated nomnom@1.8.1: Package no longer supported

npm audit 결과

# npm audit 출력
found 12 vulnerabilities (6 moderate, 4 high, 2 critical)
  critical  Prototype Pollution in lodash
  high      Command Injection in node-uuid
  moderate  Regular Expression Denial of Service in request

Analysis

deprecated 패키지 분류

패키지대체 패키지이유
requestaxios, node-fetch유지보수 중단
multermulter (최신 버전)아키텍처 변경
node-uuiduuid이름 변경
nomnomcommander유지보수 중단
momentdate-fns, dayjs번들 크기
bluebirdnative Promise네이티브 지원

마이그레이션 고려사항

  1. API 차이: 대체 패키지의 API가 다를 수 있음
  2. 의존성 영향: 다른 패키지들이 영향을 받을 수 있음
  3. 테스트 필요: 마이그레이션 후 전체 테스트 필요

Solution

1. request → axios 마이그레이션

// 기존 코드 (request 사용)
const request = require('request');

function fetchData(url) {
    return new Promise((resolve, reject) => {
        request({
            url: url,
            json: true,
            headers: {
                'User-Agent': 'MyApp/1.0',
            },
        }, (error, response, body) => {
            if (error) reject(error);
            else resolve(body);
        });
    });
}

// 마이그레이션 후 (axios 사용)
const axios = require('axios');

async function fetchData(url) {
    const response = await axios.get(url, {
        headers: {
            'User-Agent': 'MyApp/1.0',
        },
    });
    return response.data;
}

// POST 요청 비교
// 기존: request.post({ url, json: true, body }, callback)
// 변경: axios.post(url, body)

2. multer 업데이트 및 설정

// 기존 코드 (multer v1)
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });

// 최신 버전으로 업데이트
const multer = require('multer');

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, 'uploads/');
    },
    filename: (req, file, cb) => {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
        cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
    },
});

const fileFilter = (req, file, cb) => {
    const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
    if (allowedTypes.includes(file.mimetype)) {
        cb(null, true);
    } else {
        cb(new Error('Invalid file type'), false);
    }
};

const upload = multer({
    storage: storage,
    fileFilter: fileFilter,
    limits: {
        fileSize: 5 * 1024 * 1024, // 5MB
    },
});

3. node-uuid → uuid 마이그레이션

// 기존 코드
const uuid = require('node-uuid');
const id = uuid.v4();

// 변경 후
const { v4: uuidv4 } = require('uuid');
const id = uuidv4();

// TypeScript 타입 지원
import { v4 as uuidv4 } from 'uuid';
const id: string = uuidv4();

4. moment → dayjs 마이그레이션

// 기존 코드 (moment)
const moment = require('moment');
const formatted = moment().format('YYYY-MM-DD');
const diff = moment().diff(moment('2020-01-01'), 'days');

// 마이그레이션 후 (dayjs)
const dayjs = require('dayjs');
const formatted = dayjs().format('YYYY-MM-DD');

// 플러그인 사용
const relativeTime = require('dayjs/plugin/relativeTime');
dayjs.extend(relativeTime);
const fromNow = dayjs('2020-01-01').fromNow();

5. 자동 마이그레이션 스크립트

#!/usr/bin/env node

const fs = require('fs');
const { execSync } = require('child_process');

// deprecated 패키지 매핑
const deprecatedPackages = {
    'request': 'axios',
    'node-uuid': 'uuid',
    'nomnom': 'commander',
    'moment': 'dayjs',
    'bluebird': null, // 네이티브 Promise 사용
};

// package.json 읽기
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));

// deprecated 패키지 확인
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };

Object.keys(deprecatedPackages).forEach(pkg => {
    if (deps[pkg]) {
        console.log(`Found deprecated package: ${pkg}`);

        const replacement = deprecatedPackages[pkg];
        if (replacement) {
            console.log(`  Replacement: ${replacement}`);

            // 새 패키지 설치
            execSync(`npm install ${replacement}`);

            // 코드에서 마이그레이션 안내
            console.log(`  Please update your code to use ${replacement}`);
        } else {
            console.log(`  Use native implementation`);
        }
    }
});

console.log('\nMigration guide completed.');

6. package.json 업데이트 스크립트

#!/bin/bash

# deprecated 패키지 제거 및 대체 패키지 설치
remove_and_install() {
    local old=$1
    local new=$2

    echo "Removing $old and installing $new..."
    npm uninstall $old
    npm install $new
}

# 사용법
remove_and_install "request" "axios"
remove_and_install "node-uuid" "uuid"
remove_and_install "moment" "dayjs"

Lessons Learned

  1. 정기적 검사: npm auditnpm outdated를 정기적으로 실행하세요
  2. 대체 패키지 조사: deprecated 패키지의 대체 패키지를 신중하게 선택하세요
  3. 단계적 마이그레이션: 한 번에 모든 패키지를 마이그레이션하지 말고 단계적으로 진행하세요
  4. 테스트 커버리지: 마이그레이션 후 충분한 테스트를 수행하세요
  5. 문서화: 마이그레이션 과정과 변경 사항을 문서화하세요

This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.