콘텐츠로 이동

프로젝트 빌드 중 SourceMap 업로드

Guance은 현재 Vite 플러그인을 제공하여 Web 프로젝트 빌드 중에 해당 디렉터리의 SourceMap 파일을 쉽게 업로드할 수 있습니다.

참고: 현재 Web 애플리케이션 업로드만 지원됩니다.

사전 준비

  1. 해당 사이트의 OpenApi 도메인 주소를 획득합니다.
  2. Guance에서 해당 OpenApi에 필요한 API KEY획득합니다.
  3. Guance에서 Web 애플리케이션의 applicationId, env, version 정보를 획득합니다. 애플리케이션이 없으면 새 애플리케이션을 생성해야 합니다.
  4. 준비 완료.

Vite

@cloudcare/vite-plugin-sourcemap 설치

Using npm:

npm install @cloudcare/vite-plugin-sourcemap --save-dev

Using yarn:

yarn add @cloudcare/vite-plugin-sourcemap --dev

Using pnpm:

pnpm add @cloudcare/vite-plugin-sourcemap --save-dev

vite.config.js 파일의 plugins 옵션 수정

// vite.config.ts
import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"
import { SourceMapUploadVitePlugin } from "@cloudcare/vite-plugin-sourcemap"
// https://vitejs.dev/config/
export default defineConfig({
  build: {
    sourcemap: true, // Source map 생성은 반드시 활성화해야 합니다
  },
  plugins: [
    vue(),

    SourceMapUploadVitePlugin({
      applicationId: "xxxxx", //  Guance 애플리케이션 appid
      apiKey: "xxxxxxxx", // open apikey
      server: "https://console.xx-xxx.cn", // 사이트에 해당하는 openapi 주소
      filepaths: ["dist/"], // 검색할 디렉터리, 파일 또는 파일 디렉터리 가능
      logLevel: "verbose", // 로그 출력 레벨
      //   root: 'dist/', // 업로드할 상대 디렉터리에 해당하는 루트 디렉터리
      env: "production", // Guance 애플리케이션의 env
      version: "1.0.0", // Guance 애플리케이션의 version
    }),
  ],
})

Sourcemap Plugin Options

interface Options {
  /**
   *
   * Sourcemap을 검색할 파일/디렉터리입니다.
   * "extensions 구성" 목록과 일치하지만 "ignore 구성"과 일치하지 않는 모든 파일이 검색됩니다.
   * sourcemap JSON 또는 `//#sourceMappingURL=` 주석을 통해 생성된 파일 + 소스 맵 쌍을 찾은 후
   * 소스 맵이 업로드됩니다.
   */
  filepaths: Array<string> | string

  /**
   * Guance 플랫폼에서 생성된 openApi Key입니다. 생성 방법은 (https://docs.guance.com/ko/management/api-key/open-api/#_1)을 참조하세요.
   */
  apiKey: string

  /**
   * Guance 플랫폼 OpenAPI 서비스입니다.
   */
  server: string
  /**
   * Guance RUM 애플리케이션에 해당하는 applicationId(필수)
   */
  applicationId: string
  /**
   * Guance RUM 애플리케이션에 해당하는 version(선택 사항)
   */
  version?: string
  /**
   * Guance RUM 애플리케이션에 해당하는 env(선택 사항)
   */
  env?: string

  /**
   * 조건에 맞는 모든 파일 목록을 찾지만 파일을 업로드하지는 않습니다. 디버깅에 사용할 수 있습니다.
   */
  dryRun?: boolean
  /**
   * 업로드 후 찾은 모든 소스 맵 파일을 삭제합니다.
   */
  deleteAfterUpload?: boolean
  /**
   * 소스 맵이 sourceMappingURL을 통해 생성된 파일과 일치하지 않는 경우
   * 로컬 디스크의 파일 이름을 통해 일치를 시도합니다.
   */
  matchSourcemapsByFilename: ?boolean

  /**
   * 디렉터리에서 검색할 파일 확장자 목록입니다.
   * 기본값 [".js", ".map"].
   */
  extensions?: Array<string>

  /**
   * 무시할 파일 목록입니다.
   */
  ignore?: Array<string>

  /**
   * 상대 경로를 계산할 디렉터리를 설정합니다. sourcemaps 업로드의 상대 경로는
   * 오류가 발생한 경로에 포함되어야 합니다. 따라서 이 매개변수의 목적은
   * 업로드할 상대 디렉터리를 제어하는 것입니다.
   * 기본값: 실행 디렉터리에서 검색 디렉터리까지의 상대 경로 path.relative(process.cwd(), filepath)
   */
  root?: string
  /**
   * 디버깅 시 사용되며, 생성되는 로그의 레벨입니다.
   */
  logLevel?: "quiet" | "normal" | "verbose"
  /**
   * 실행 실패 시 오류를 무시할지 여부입니다. 이 설정을 사용하면 오류 발생 시
   * 컴파일 프로세스가 중단되지 않습니다. 기본값 false, 즉 정상적으로 오류를 발생시킵니다.
   */
  warnOnFailure?: boolean
}

프로덕션 환경에서 Sourcemap의 가시성

프로덕션 환경에서는 보안상의 이유로 시스템이 일반적으로 sourcemap 파일을 보관하지 않습니다. 이러한 파일은 개발자가 압축 또는 컴파일된 코드를 원본 소스 코드로 매핑할 수 있게 해주지만, 공개될 경우 애플리케이션의 내부 로직이 노출되어 보안 위험이 증가할 수 있습니다.

Sourcemap을 안전하게 처리하기 위해 SourceMapUploadVitePlugin을 구성할 때 deleteAfterUpload: true 옵션을 활성화할 수 있습니다. 이렇게 하면 sourcemap이 서버에 업로드되는 즉시 로컬 파일 시스템에서 삭제되어 프로덕션 환경에 남지 않도록 보장합니다.

또한 vite.config.ts에서 build.sourcemap을 "hidden"으로 설정하면 JavaScript 파일에 소스 맵에 대한 참조를 포함하지 않고 Sourcemap을 생성할 수 있습니다. 이렇게 하면 브라우저가 소스 코드를 다운로드하여 보려는 시도를 방지할 수 있습니다.

"hidden"이 활성화된 경우, SourceMapUploadVitePlugin 플러그인에서 matchSourcemapsByFilename: true도 설정해야 합니다. 이 구성은 생성된 코드에 명시적인 참조가 없더라도 플러그인이 JavaScript 파일 이름을 기반으로 해당 Sourcemap 파일을 식별하고 업로드할 수 있도록 보장합니다.

이러한 조치를 통해 애플리케이션 디버깅의 편의성을 유지하면서도 소스 코드의 보안을 효과적으로 보호할 수 있습니다.

// vite.config.ts
import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"
import { SourceMapUploadVitePlugin } from "@cloudcare/vite-plugin-sourcemap"
// https://vitejs.dev/config/
export default defineConfig({
  build: {
    sourcemap: "hidden", // Source map 생성은 반드시 활성화해야 합니다
  },
  plugins: [
    vue(),

    SourceMapUploadVitePlugin({
      applicationId: "xxxxx", //  Guance 애플리케이션 appid
      apiKey: "xxxxxxxx", // open apikey
      server: "https://console.xxx-xxx.cn",
      filepaths: ["dist/"], // 검색할 디렉터리, 파일 또는 파일 디렉터리 가능
      logLevel: "verbose", // 로그 출력 레벨
      //   root: 'dist/', // 업로드할 상대 디렉터리에 해당하는 루트 디렉터리
      env: "production", // Guance 애플리케이션의 env
      version: "1.0.0", // Guance 애플리케이션의 version
      deleteAfterUpload: true,
      matchSourcemapsByFilename: true,
    }),
  ],
})

DEBUG 방법

실행 중에 해당 Sourcemap을 찾지 못한 경우, 환경 변수 DEBUG=sourcemap-upload를 설정하거나 logLevel: verbose를 구성하여 build 명령을 실행하고 구체적인 실행 로그를 확인할 수 있습니다.

주의사항

  • Node 버전 > 16;

  • filepathsroot 구성 시 주의사항:

콘솔에 오류 메시지 중 한 줄이 at SVGGElement.<anonymous> @ http://localhost:8000/js/chunk-vendors.732b3b98.js:1:93427과 같이 표시됩니다. 오류를 발생시킨 파일의 상대 경로는 js/chunk-vendors.732b3b98.js입니다. JS 파일이 서버의 정적 디렉터리에 dist/js/*.js dist/js/*.js.map으로 있는 경우, 플러그인 구성은 filepaths: ['dist']입니다.

root를 구성하지 않은 경우 기본값은 dist/이며, 최종적으로 서버에 업로드되는 Sourcemap 파일 경로는 dist/js/**.js.map입니다. 이 경우 업로드된 파일의 디렉터리 경로오류가 발생한 경로가 일치하지 않게 됩니다. 따라서 이때는 root:'/' 또는 root: '' 구성을 추가하여 업로드된 디렉터리 경로가 js/**.js.map이 되도록 보장해야 합니다.

문서 평가

이 페이지가 도움이 되었나요?