Mermaid 실전 가이드: 설정부터 렌더링까지 완벽 문제 해결 핸드북

Mermaid는 JavaScript 기반의 다이어그램 생성 도구로, 마크다운과 유사한 텍스트 정의를 통해 플로우차트, 시퀀스 다이어그램 등 다양한 차트를 빠르게 만들 수 있게 해줍니다. 이 가이드는 Mermaid 초보자 또는 기술적 문제에 직면한 개발자를 위해 설계되었으며, 환경 설정부터 성능 최적화까지 실제 개발에서 가장 자주 발생하는 문제에 대한 완벽한 솔루션을 제공합니다.

환경 설정

설치 오류 해결: 의존성 문제 빠르게 수정하기

증상: npm install mermaid 실행 시 ERR! 오류가 발생하거나, 설치 후 실행 시 모듈 누락 메시지가 나타납니다. 일반적으로 Node.js 버전 불일치나 npm 캐시 오류가 원인입니다.

해결 방법:

  1. Node.js 버전 확인: LTS 버전(16.x 또는 18.x 권장)을 사용 중인지 node -v로 확인합니다.
  2. npm 캐시 정리: npm cache clean --force 실행
  3. 특정 버전 재설치: npm install mermaid@latest (필요 시 latest 대신 10.6.1 등 특정 버전 지정)

예방 전략:

  • 프로젝트 루트에 .nvmrc 파일을 생성하여 Node.js 버전 고정: echo "18.18.0" > .nvmrc
  • npm-force-resolutions을 사용하여 의존성 충돌 해결:
    json "resolutions": { "mermaid/**/dagre": "0.8.5" }
  • 정기적으로 npm audit 실행하여 보안 취약점 확인 및 수정

💡 국내 사용자는淘宝 npm 미러를 사용하여 설치 속도를 높일 수 있습니다: npm install mermaid --registry=https://registry.npmmirror.com

설정 파일이 적용되지 않을 때: 환경 변수 우선순위 이해하기

증상: mermaid.config.js를 수정해도 차트 스타일이 변경되지 않거나, 일부 설정이 덮어쓰여집니다. Mermaid의 다중 계층 설정 우선순위로 인해 발생하는 일반적인 문제입니다.

해결 방법:

  1. 설정 로딩 순서 확인: 기본 설정 < 전역 초기화 설정 < 차트 내 지시문 설정
  2. API를 사용하여 기본 설정 재정의:
    mermaid.initialize({
      theme: 'dark',
      logLevel: 1,
      securityLevel: 'loose'
    });
    
  3. 차트 앞에 프론트매터(frontmatter) 설정 추가 (v10.5.0+):
    ---
    title: 내 차트
    config:
      theme: forest
    ---
    flowchart LR
      A-->B
    

예방 전략:

  • 프로젝트 수준의 mermaid.config.js 파일을 생성하여 설정을 중앙 관리
  • 여러 곳에 동일한 설정을 두지 말고, 차트 내 설정 > 전역 설정 순서로 우선순위를 지정
  • mermaidAPI.getConfig()를 사용하여 현재 적용된 설정 디버깅

기능 구현

차트가 빈 화면으로 표시될 때: 렌더링 실패 문제 해결

증상: 페이지 로드 후 차트 영역이 비어 있고, 브라우저 콘솔에 Uncaught ReferenceError: mermaid is not defined 또는 Failed to execute 'querySelector' on 'Document' 오류가 나타납니다.

해결 방법:

  1. DOM 로딩 순서 확인: DOM 요소가 로드된 후에 렌더링이 호출되도록 합니다.
    document.addEventListener('DOMContentLoaded', function() {
      mermaid.init(undefined, '.mermaid');
    });
    
  2. 차트 컨테이너 요소가 존재하고 classmermaid인지 확인:
    <div class="mermaid">
      flowchart LR
        A --> B
    </div>
    
  3. 보안 수준을 낮춰 임시 테스트 (개발 환경에서만):
    mermaid.initialize({ securityLevel: 'loose' });
    

예방 전략:

  • try-catch를 사용하여 렌더링 오류를 포착하고 사용자에게 친숙한 메시지 표시:
    try {
      mermaid.render('chart1', graphDefinition);
    } catch (e) {
      console.error('Mermaid 렌더링 실패:', e);
      document.getElementById('chart-container').innerHTML =
        '<div class="error">차트 로딩 실패. 페이지를 새로고침 해주세요.</div>';
    }
    
  • 개발 환경에서 디버그 모드 활성화: mermaid.initialize({ logLevel: 0 })로 상세 로그 확인

중국어 깨짐 또는 폰트 오류: 폰트 설정 완벽 해결

증상: 차트 내 중국어가 네모 또는 겹쳐서 표시되지만, 영어는 정상입니다. Mermaid 기본 폰트가 중국어 문자를 지원하지 않기 때문입니다.

해결 방법:

  1. CSS를 통해 차트 폰트 사용자 정의:
    .mermaid {
      font-family: "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
    }
    
  2. 설정에서 전역 폰트 지정:
    mermaid.initialize({
      themeVariables: {
        fontFamily: '"Microsoft YaHei", sans-serif'
      }
    });
    
  3. 특수 차트(간트 차트 등)에 대해 별도 폰트 설정

예방 전략:

  • 프로젝트 전역 CSS에서 Mermaid 폰트 스타일을 미리 정의
  • 웹 폰트(Web Font)를 사용하여 플랫폼 간 폰트 일관성 유지:
    @font-face {
      font-family: 'CustomFont';
      src: url('/fonts/custom-font.woff2') format('woff2');
      font-display: swap;
    }
    
  • 차트 텍스트에 여러 언어를 혼합하지 않도록 주의

성능 최적화

대형 차트 로딩 속도 저하: 분할 렌더링 최적화

증상: 50개 이상의 노드를 가진 복잡한 플로우차트가 느리게 로드되고, 페이지가 심하게 버벅이거나 멈춥니다. Mermaid가 차트 전체를 한 번에 렌더링하기 때문에 발생하는 성능 병목 현상입니다.

해결 방법:

  1. 차트를 분할하여 렌더링하고, 먼저 보이는 영역부터 처리:
    // 첫 번째 차트만 렌더링
    mermaid.init(undefined, '.mermaid:first-of-type');
    
  2. 차트 복잡도 줄이기, 보조 노드 병합
  3. maxTextSize를 사용하여 노드 텍스트 길이 제한:
    mermaid.initialize({
      maxTextSize: 50 // 50자를 초과하면 잘림
    });
    

예방 전략:

  • 초대형 차트의 경우 지연 로딩(lazy loading)을 구현하여 스크롤 시에만 렌더링
  • mermaidAPI.render()를 사용하여 자동 렌더링 대신 수동으로 렌더링 시점 제어
  • 초대형 차트를 여러 개의 작은 하위 차트로 분할하는 것을 고려

빈번한 업데이트로 인한 화면 깜빡임: DOM 조작 최적화

증상: 차트 데이터를 동적으로 업데이트할 때 심한 깜빡임이 발생하거나 페이지 레이아웃이 자주 재배열됩니다. 매 업데이트마다 DOM 요소를 완전히 재생성하기 때문입니다.

해결 방법:

  1. 가상 DOM 컨테이너를 사용하여 리페인트(repaint) 최소화:
    function updateChart(newDefinition) {
      const container = document.getElementById('chart-container');
      // 업데이트 전에 숨김
      container.style.visibility = 'hidden';
      mermaid.render('chart', newDefinition, (svgCode) => {
        container.innerHTML = svgCode;
        // 업데이트 완료 후 표시
        container.style.visibility = 'visible';
      });
    }
    
  2. 디바운스(debounce) 함수를 사용하여 업데이트 빈도 제한:
    const debouncedUpdate = debounce(updateChart, 300);
    // 입력 필드 변경 시 디바운스된 업데이트 트리거
    document.getElementById('chart-input').addEventListener('input', (e) => {
      debouncedUpdate(e.target.value);
    });
    

예방 전략:

  • CSS will-change: transform을 사용하여 브라우저에 렌더링 최적화 힌트 제공
  • SVG 요소에 preserveAspectRatio 속성을 적용하여 레이아웃 안정성 유지
  • 복잡한 상호작용 차트의 경우 Web Worker를 사용하여 데이터 계산 처리

보안 및 호환성

XSS 취약점 경고: 안전한 설정 모범 사례

증상: 콘솔에 보안 경고가 나타나거나, 외부 차트 데이터를 로드할 때 브라우저가 차단합니다. Mermaid 8.4.0부터 보안 검사가 강화되어 잠재적으로 위험한 코드 실행이 기본적으로 금지됩니다.

해결 방법:

  1. 사용 환경에 따라 보안 수준 조정 (엄격 → 느슨):
    // 가장 엄격: 모든 외부 리소스 및 JS 실행 금지 (기본값)
    mermaid.initialize({ securityLevel: 'strict' });
    // 중간: 일부 안전한 속성 허용
    mermaid.initialize({ securityLevel: 'loose' });
    // 가장 낮음: 완전히 신뢰할 수 있는 환경에서만 사용
    mermaid.initialize({ securityLevel: 'antiscript' });
    
  2. 샌드박스 모드를 사용하여 신뢰할 수 없는 콘텐츠 렌더링:
    <iframe sandbox="allow-same-origin" src="trusted-renderer.html"></iframe>
    

예방 전략:

  • strict 모드에서는 절대 사용자가 제출한 차트 코드를 렌더링하지 마세요.
  • Content-Security-Policy를 사용하여 스크립트 실행 제한:
    Content-Security-Policy: default-src 'self'; script-src 'self'
    
  • 차트 코드 필터를 구현하여 안전한 Mermaid 구문 요소만 허용

브라우저 호환성 문제: 교차 브라우저 적응 솔루션

증상: Chrome에서는 차트가 정상이지만 Safari나 구형 Edge에서는 레이아웃이 깨지거나 렌더링되지 않습니다. 브라우저의 SVG 및 CSS 기능 지원 차이 때문입니다.

해결 방법:

  1. SVG 호환성 접두사 추가:
    .mermaid svg {
      width: 100% !important;
      height: auto !important;
      /* IE 및 구형 Edge 레이아웃 문제 수정 */
      overflow: visible;
    }
    
  2. Safari를 위한 특별 처리:
    @supports (-webkit-overflow-scrolling: touch) {
      .mermaid {
        transform: translateZ(0); /* 하드웨어 가속 트리거 */
      }
    }
    

예방 전략:

  • package.jsonbrowserslist를 추가하여 지원할 브라우저 범위 지정
  • polyfill을 사용하여 누락된 ES6+ 기능 보충: import 'core-js/stable';
  • 대상 브라우저에서 정기적으로 차트 렌더링 테스트

고급 응용

사용자 정의 차트 타입 개발: 플러그인 시스템 실전 가이드

증상: 내장 차트 타입으로 특정 비즈니스 요구를 충족할 수 없어 사용자 정의 차트가 필요합니다. Mermaid는 새로운 차트 타입 확장을 위한 유연한 플러그인 시스템을 제공합니다.

해결 방법:

  1. 사용자 정의 차트 감지기(detector) 생성:
    // 사용자 정의 차트 감지기
    export const detector = (text) => {
      return text.match(/^\s*customDiagram/) ? 1 : 0;
    };
    
  2. 파서(parser) 및 렌더러(renderer) 구현:
    // 간소화된 사용자 정의 렌더러 예시
    export const renderer = (svg, diagram, config) => {
      svg.innerHTML = `<g><text x="50" y="50">${diagram.title}</text></g>`;
    };
    
  3. 사용자 정의 차트 등록:
    mermaid.registerDiagram('customDiagram', {
      detector,
      parser,
      renderer
    });
    

예방 전략:

  • 공식 예제 프로젝트 구조 참조: packages/mermaid-example-diagram/
  • 사용자 정의 차트에 대한 단위 테스트 작성하여 안정성 보장
  • Mermaid의 명명 규칙 및 코드 스타일 준수

서버 사이드 렌더링 미작동: Node.js 환경 설정 안내

증상: Node.js 환경에서 mermaid.render() 사용 시 출력이 없거나 오류가 발생합니다. 서버 사이드 렌더링에서 흔히 발생하는 환경 미비 문제입니다.

해결 방법:

  1. 필요한 의존성 설치: npm install mermaid puppeteer
  2. Headless 브라우저 환경 구성:
    const { render } = require('mermaid-cli');
    
    async function generateSvg(code) {
      return await render('temp.svg', code, {
        puppeteerConfig: { args: ['--no-sandbox'] }
      });
    }
    
  3. 비동기 렌더링 처리:
    (async () => {
      try {
        const svg = await generateSvg('flowchart LR A-->B');
        console.log(svg);
      } catch (e) {
        console.error('렌더링 실패:', e);
      }
    })();
    

예방 전략:

  • 서버 환경에 적절한 메모리 제한 설정 (복잡한 차트는 더 많은 메모리 필요)
  • 캐시 메커니즘을 사용하여 이미 생성된 차트 저장, 중복 렌더링 방지
  • 렌더링 큐 구현, 동시 렌더링으로 인한 리소스 경쟁 방지

태그: mermaid JavaScript 다이어그램 렌더링 Node.js

6월 24일 04:44에 게시됨