imqa.document

@imqa/vite-sourcemap

Vite 플러그인으로 빌드 후 소스맵을 자동으로 업로드합니다. IMQA 서비스에 소스맵을 업로드하여 프로덕션 환경에서 발생한 에러의 원본 소스코드 위치를 추적할 수 있습니다.

Latest Release

NPM Version NPM Last Update NPM Unpacked Size npm package minimized gzipped size NPM Downloads NPM Type Definitions

Vite 플러그인으로 빌드 후 소스맵을 자동으로 업로드합니다. IMQA 서비스에 소스맵을 업로드하여 프로덕션 환경에서 발생한 에러의 원본 소스코드 위치를 추적할 수 있습니다.

기능

  • Vite 빌드 완료 후 소스맵 자동 업로드
  • 포함/제외 패턴으로 파일 필터링
  • gzip 압축 지원
  • 동시 업로드 제한 및 재시도 로직
  • CI 환경 감지
  • 업로드 후 로컬 소스맵 파일 삭제 옵션
  • 커스텀 경로 변환 및 URL 접두사 지원

설치

npm install @imqa/vite-sourcemap --save-dev

폐쇄망 설치

NoteNote

외부 네트워크에 접근할 수 없는 폐쇄망 환경에서는 아래 방법 중 하나를 선택하여 설치합니다.

NoteNote

폐쇄망에서는 CDN을 통해 직접 실행할 수 없으므로 인터넷이 연결된 환경에서 미리 번들링된 자바스크립트 파일을 다운로드를 받습니다. /imqa-vite-sourcemap-latest.tgz

Option 1: .tgz 파일 다운로드 후 npm install

  1. imqa-vite-sourcemap-latest.tgz 파일을 다운로드합니다.
imqa-vite-sourcemap-latest.tgz 다운로드
  1. 프로젝트 내부 적절한 경로에 배치 후 npm install로 설치합니다.
npm install /path/to/imqa-vite-sourcemap-latest.tgz --save-dev

예를 들어 프로젝트 구조가 아래와 같이 되어 있다면

.
├── package.json
├── src
│   └── ...
├── third-party-packages
│   └── imqa
│       └── imqa-vite-sourcemap-latest.tgz
└── vite.config.ts

아래와 같이 설치합니다.

npm install ./third-party-packages/imqa/imqa-vite-sourcemap-latest.tgz --save-dev

이후 사용법 섹션을 참고하여 설정을 진행합니다.

Option 2: npm install을 사용할 수 없는 경우

  1. imqa-vite-sourcemap-latest.tgz 파일을 다운로드 후 압축 해제합니다.
imqa-vite-sourcemap-latest.tgz 다운로드
  1. 프로젝트 node_modules/@imqa/vite-sourcemap 폴더에 압축 해제된 package 내의 파일들을 복사합니다.
mkdir -p node_modules/@imqa/vite-sourcemap
tar -xzf imqa-vite-sourcemap-latest.tgz
cp -r package/* node_modules/@imqa/vite-sourcemap/
rm -rf package

이후 사용법 섹션을 참고하여 설정을 진행합니다.

사용법

기본 설정

// vite.config.ts
import { defineConfig } from 'vite'
import sourcemapUpload from '@imqa/vite-sourcemap'

export default defineConfig({
  build: {
    sourcemap: true, // 중요: 소스맵 생성을 활성화해야 합니다
  },
  plugins: [
    sourcemapUpload({
      endpoint: 'https://api.your-service.imqa.io/api/sourcemaps',
      apiKey: process.env.SOURCEMAP_API_KEY,
      release: process.env.GIT_SHA,
      appVersion: process.env.npm_package_version,
    }),
  ],
})

고급 설정

// vite.config.ts
import { defineConfig } from 'vite'
import sourcemapUpload from '@imqa/vite-sourcemap'

export default defineConfig({
  build: {
    sourcemap: true,
  },
  plugins: [
    sourcemapUpload({
      // 필수: 업로드 엔드포인트
      endpoint: 'https://api.your-service.imqa.io/api/sourcemaps',
      
      // 인증
      apiKey: process.env.SOURCEMAP_API_KEY,
      
      // 릴리즈 정보
      release: process.env.GIT_SHA,
      appVersion: process.env.npm_package_version,
      build: process.env.BUILD_NUMBER,

      // 앱 타입 (플랫폼별 소스맵 구분)
      appType: 'ALL', // 'ANDROID' | 'IOS' | 'WEB' | 'ALL' | null

      // 파일 필터링
      include: [/assets\/.+\.js\.map$/],
      exclude: [/node_modules/],
      
      // CDN 경로 설정
      urlPrefix: '~/static/js',
      
      // 커스텀 경로 변환
      transformPath: (path) => `build/${path}`,
      
      // 업로드 설정
      concurrency: 3,
      retries: 5,
      gzip: true,
      deleteAfterUpload: true,
      
      // CI에서만 실행
      ciOnly: true,
      
      // 추가 헤더
      headers: {
        'X-Custom-Header': 'value',
      },
      
      // 추가 폼 필드
      fields: {
        environment: 'production',
        team: 'frontend',
      },
    }),
  ],
})

설정 옵션

필수 옵션

옵션타입설명
endpointstring소스맵을 업로드할 API 엔드포인트

선택 옵션

옵션타입기본값설명
method'POST' | 'PUT''POST'HTTP 메서드
headersRecord<string, string>{}추가 HTTP 헤더
apiKeystring-Bearer 토큰 또는 API 키
releasestring-릴리즈 식별자 (예: git SHA)
appVersionstring-앱 버전 (semver)
buildstring-빌드 번호 또는 CI 빌드 ID
appType'ANDROID' | 'IOS' | 'WEB' | 'ALL' | nullnull앱 타입 (플랫폼별 소스맵 구분)
fileFieldNamestring'file'파일 업로드용 폼 필드명
fieldsRecord<string, string | number | boolean>{}추가 폼 필드
include(string | RegExp)[]-포함할 파일 패턴
exclude(string | RegExp)[]-제외할 파일 패턴
urlPrefixstring-업로드 파일명에 추가할 접두사
transformPath(path: string) => string-경로 변환 함수
concurrencynumber6동시 업로드 수
retriesnumber3재시도 횟수
gzipbooleantruegzip 압축 사용 여부
deleteAfterUploadbooleanfalse업로드 후 로컬 파일 삭제
ciOnlybooleanfalseCI 환경에서만 실행
verbosebooleanCI에서 true, 로컬에서 false상세 로그 출력

CI 환경 감지

플러그인은 다음 환경 변수를 통해 CI 환경을 자동으로 감지합니다:

  • CI
  • GITHUB_ACTIONS
  • GITLAB_CI
  • BUILDKITE
  • CIRCLECI
  • TRAVIS
  • BITBUCKET_BUILD_NUMBER

환경 변수 예시

# .env 파일
SOURCEMAP_API_KEY=your-api-key
GIT_SHA=$(git rev-parse HEAD)
BUILD_NUMBER=$CI_BUILD_NUMBER

사용 예시

sourcemapUpload({
  endpoint: 'https://api.your-service.imqa.io/api/sourcemaps',
  apiKey: process.env.IMQA_AUTH_TOKEN,
  release: process.env.IMQA_SERVICE_NAME,
  urlPrefix: '~/dist/',
  include: [/\.js\.map$/],
  ciOnly: true,
})

GitHub Actions와 함께 사용

# .github/workflows/deploy.yml
- name: Build and upload sourcemaps
  env:
    SOURCEMAP_API_KEY: ${{ secrets.SOURCEMAP_API_KEY }}
    GIT_SHA: ${{ github.sha }}
  run: npm run build

문제 해결

소스맵이 업로드되지 않는 경우

  1. build.sourcemap: true가 설정되어 있는지 확인
  2. endpoint가 올바른지 확인
  3. verbose: true로 설정하여 상세 로그 확인
  4. include/exclude 패턴이 올바른지 확인

CI에서만 실행하고 싶은 경우

sourcemapUpload({
  // ... 기타 설정
  ciOnly: true, // 로컬에서는 실행되지 않음
})

특정 파일만 업로드하고 싶은 경우

sourcemapUpload({
  // ... 기타 설정
  include: [/assets\/.+\.js\.map$/], // assets 폴더의 JS 소스맵만
  exclude: [/vendor/, /node_modules/], // vendor, node_modules 제외
})

플랫폼별 소스맵 (appType)

ServiceNamespace 또는 Service 레벨에서 플랫폼별로 소스맵을 구분하여 관리할 수 있습니다.

공통 WebView (모든 플랫폼)

Android/iOS/Web에서 공통으로 사용하는 WebView 소스맵:

sourcemapUpload({
  endpoint: 'https://api.imqa.io/v1/web-sourcemaps',
  apiKey: process.env.IMQA_ACCESS_TOKEN,
  appVersion: '1.0.0',
  appType: 'ALL', // 모든 플랫폼에서 사용
})

Android WebView 전용

sourcemapUpload({
  endpoint: 'https://api.imqa.io/v1/web-sourcemaps',
  apiKey: process.env.IMQA_ACCESS_TOKEN,
  appVersion: '1.0.0',
  appType: 'ANDROID',
})

iOS WebView 전용

sourcemapUpload({
  endpoint: 'https://api.imqa.io/v1/web-sourcemaps',
  apiKey: process.env.IMQA_ACCESS_TOKEN,
  appVersion: '1.0.0',
  appType: 'IOS',
})

Web 브라우저 전용

sourcemapUpload({
  endpoint: 'https://api.imqa.io/v1/web-sourcemaps',
  apiKey: process.env.IMQA_ACCESS_TOKEN,
  appVersion: '1.0.0',
  appType: 'WEB',
})

레거시 (appType 미지정)

기존 방식과의 호환성을 위해 appType을 지정하지 않으면 모든 플랫폼에서 fallback으로 사용됩니다:

sourcemapUpload({
  endpoint: 'https://api.imqa.io/v1/web-sourcemaps',
  apiKey: process.env.IMQA_ACCESS_TOKEN,
  appVersion: '1.0.0',
  // appType 미지정 = null (레거시 호환)
})