마이그레이션 가이드

기존 컴파일러(lingo.dev/compiler)에서 새로운 @lingo.dev/compiler로 마이그레이션하세요.

왜 마이그레이션해야 하나요?

새로운 컴파일러는 다음을 제공합니다:

  • 향상된 개발자 경험 — 기본적으로 자동화('use i18n' 불필요)
  • 향상된 성능 — 더 빠른 빌드, 개선된 HMR
  • 빌드 모드 — 개발/CI/프로덕션 관심사 분리
  • 수동 오버라이드data-lingo-override 속성
  • 커스텀 로케일 리졸버 — 유연한 로케일 감지
  • 개발 도구 — 의사 번역기, 개발 위젯(출시 예정)
  • 깔끔한 아키텍처 — 향상된 관심사 분리

주요 변경 사항

1. 패키지 이름

기존:

npm install lingo.dev

신규:

npm install @lingo.dev/compiler

2. 임포트 경로

기존:

import lingoCompiler from "lingo.dev/compiler";
import { LingoProvider } from "lingo.dev/react/rsc";

신규:

import { withLingo } from "@lingo.dev/compiler/next";
import { LingoProvider } from "@lingo.dev/compiler/react";

3. 설정 API

Next.js

기존:

// next.config.js
import lingoCompiler from "lingo.dev/compiler";

export default lingoCompiler.next({
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  models: "lingo.dev",
})(nextConfig);

신규:

// next.config.ts
import { withLingo } from "@lingo.dev/compiler/next";

export default async function (): Promise<NextConfig> {
  return await withLingo(nextConfig, {
    sourceRoot: "./app", // New: specify source directory
    sourceLocale: "en",
    targetLocales: ["es", "de"],
    models: "lingo.dev",
  });
}

변경 사항:

  • 설정은 비동기 함수여야 합니다
  • 새로운 sourceRoot 옵션
  • lingoCompiler.next 대신 withLingo 래퍼 사용

Vite

기존:

import lingoCompiler from "lingo.dev/compiler";

export default defineConfig(() =>
  lingoCompiler.vite({
    sourceRoot: "src",
    targetLocales: ["es", "de"],
    models: "lingo.dev",
  })(viteConfig)
);

신규:

import { lingoCompilerPlugin } from "@lingo.dev/compiler/vite";

export default defineConfig({
  plugins: [
    lingoCompilerPlugin({
      sourceRoot: "src",
      sourceLocale: "en", // New: required
      targetLocales: ["es", "de"],
      models: "lingo.dev",
    }),
    react(),
  ],
});

변경 사항:

  • 설정 래퍼 대신 플러그인 기반
  • sourceLocale가 이제 필수입니다
  • react() 플러그인 앞에 배치

4. 프로바이더 설정

기존:

import { LingoProvider, loadDictionary } from "lingo.dev/react/rsc";

export default function Layout({ children }) {
  return (
    <LingoProvider loadDictionary={(locale) => loadDictionary(locale)}>
      {children}
    </LingoProvider>
  );
}

신규:

import { LingoProvider } from "@lingo.dev/compiler/react";

export default function Layout({ children }) {
  return (
    <LingoProvider>
      {children}
    </LingoProvider>
  );
}

변경 사항:

  • loadDictionary prop 없음—내부적으로 처리됨
  • 더 간단한 API

5. 파일 구조

기존:

lingo/
├── dictionary.js
├── meta.json
└── [locale]/
    └── *.json

신규:

.lingo/
└── metadata.json

변경 사항:

  • 디렉터리 이름 변경(.lingo vs lingo)
  • 여러 파일 대신 단일 메타데이터 파일
  • 다른 JSON 구조

6. "use i18n" 지시문

기존: 기본적으로 필수입니다. 번역하려는 모든 파일에 추가하세요:

'use i18n';

export function Component() { ... }

신규: 선택 사항입니다. 기본적으로 모든 파일이 자동으로 번역됩니다. 옵트인하려면:

{
  useDirective: true, // Enable opt-in behavior
}

그런 다음 지시문을 추가하세요:

'use i18n';

export function Component() { ... }

마이그레이션 단계

1단계: 패키지 업데이트

# Uninstall old package
npm uninstall lingo.dev

# Install new package
npm install @lingo.dev/compiler

2단계: 구성 업데이트

Next.js

이전:

// next.config.js
import lingoCompiler from "lingo.dev/compiler";

export default lingoCompiler.next({
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  models: "lingo.dev",
})(nextConfig);

이후:

// next.config.ts
import type { NextConfig } from "next";
import { withLingo } from "@lingo.dev/compiler/next";

const nextConfig: NextConfig = {};

export default async function (): Promise<NextConfig> {
  return await withLingo(nextConfig, {
    sourceRoot: "./app",
    sourceLocale: "en",
    targetLocales: ["es", "de"],
    models: "lingo.dev",
    dev: {
      usePseudotranslator: true, // Recommended for development
    },
  });
}

Vite

이전:

import lingoCompiler from "lingo.dev/compiler";

export default defineConfig(() =>
  lingoCompiler.vite({
    sourceRoot: "src",
    targetLocales: ["es", "de"],
    models: "lingo.dev",
  })(viteConfig)
);

이후:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { lingoCompilerPlugin } from "@lingo.dev/compiler/vite";

export default defineConfig({
  plugins: [
    lingoCompilerPlugin({
      sourceRoot: "src",
      sourceLocale: "en",
      targetLocales: ["es", "de"],
      models: "lingo.dev",
      dev: {
        usePseudotranslator: true,
      },
    }),
    react(),
  ],
});

3단계: 프로바이더 업데이트

이전:

import { LingoProvider, loadDictionary } from "lingo.dev/react/rsc";

export default function Layout({ children }) {
  return (
    <LingoProvider loadDictionary={(locale) => loadDictionary(locale)}>
      {children}
    </LingoProvider>
  );
}

이후:

import { LingoProvider } from "@lingo.dev/compiler/react";

export default function Layout({ children }) {
  return (
    <LingoProvider>
      {children}
    </LingoProvider>
  );
}

4단계: 이전 파일 정리

# Backup old translations (optional)
mv lingo lingo.backup

# Remove old directory
rm -rf lingo

# New directory will be created automatically
# on first build

5단계: 의사 번역기로 테스트

npm run dev

usePseudotranslator: true를 사용하면 즉시 가짜 번역을 확인할 수 있습니다. 다음을 확인하세요:

  • 예상되는 모든 텍스트가 번역되었는지
  • 컴파일 오류가 없는지
  • 레이아웃이 다양한 텍스트 길이를 처리하는지

6단계: 실제 번역 생성

의사 번역기를 비활성화하도록 구성을 업데이트하세요:

{
  dev: {
    usePseudotranslator: false,
  }
}

개발 서버를 재시작하세요. 컴파일러가 새로 추가되거나 변경된 텍스트에 대한 실제 번역을 생성합니다.

7단계: 새 번역 커밋

git add .lingo/
git commit -m "chore: migrate to @lingo.dev/compiler"
git push

기능 매핑

기존 기능 → 새로운 대응 기능

이전 기능새로운 대응 기능참고 사항
dictionary.js.lingo/metadata.json다른 형식
meta.json.lingo/metadata.json단일 파일로 병합됨
"use i18n" (필수)"use i18n" (선택)이제 선택 사항이며 필수 아님
사용자 정의 프롬프트prompt 설정 옵션동일한 기능
번역 편집data-lingo-override속성 기반 재정의
번역 건너뛰기data-lingo-override + 비어 있음또는 useDirective 사용
번역 재정의data-lingo-override속성 기반
로케일 전환useLingoContext(){ locale, setLocale } 반환
LLM 제공자models 설정동일한 제공자 지원

새로운 기능 (기존 컴파일러에 없음)

  • 빌드 모드translate vs cache-only
  • 의사 번역기 — 즉시 가짜 번역 생성
  • 개발 위젯 — 브라우저 내 편집 (곧 출시)
  • 커스텀 로케일 리졸버 — 유연한 로케일 감지
  • 자동 복수형 처리 — ICU MessageFormat 지원
  • 번역 서버 — 개발 환경에서 온디맨드 번역

기존 번역 변환

새 컴파일러는 다른 파일 형식을 사용합니다. 기존 번역은 자동으로 마이그레이션되지 않습니다.

옵션:

옵션 1: 모든 번역 재생성

컴파일러가 새로운 번역을 생성하도록 합니다:

  1. 기존 lingo/ 디렉토리 삭제
  2. 새 컴파일러 실행
  3. AI를 사용하여 번역 생성

장점: 깨끗한 시작, 최신 AI 모델 단점: API 비용, 뉘앙스 손실 가능성

옵션 2: 수동 마이그레이션 스크립트

기존 형식을 새 형식으로 변환하는 스크립트를 작성하세요:

// migrate-translations.ts
import * as fs from "fs";

const oldDir = "./lingo";
const newFile = "./.lingo/metadata.json";

// Read old translations
const oldTranslations = {}; // Parse old files

// Convert to new format
const newMetadata = {
  version: "1",
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  translations: {}, // Convert old translations
};

// Write new metadata
fs.writeFileSync(newFile, JSON.stringify(newMetadata, null, 2));

이는 수동 작업이며 형식에 따라 다릅니다.

옵션 3: 하이브리드 접근 방식

  1. 대부분의 텍스트에 대해 새 번역 생성
  2. 정확한 문구가 필요한 중요한 번역에는 data-lingo-override 사용

일반적인 문제

"Cannot find module '@lingo.dev/compiler'" npm install @lingo.dev/compiler를 실행하세요

"Config must be async function" (Next.js) 설정을 async function로 래핑하세요:

export default async function () {
  return await withLingo(...);
}

"sourceLocale is required" 설정에 sourceLocale: "en"를 추가하세요.

번역이 표시되지 않음 다음을 확인하세요:

  1. 루트 레이아웃에 LingoProvider가 있는지
  2. .lingo/metadata.json가 존재하는지
  3. 콘솔 오류가 없는지

FAQ

두 컴파일러를 동시에 실행할 수 있나요? 아니요. 새 컴파일러를 설치하기 전에 기존 컴파일러를 제거해야 합니다.

번역이 손실되나요? 수동으로 마이그레이션하면 손실되지 않습니다. 그렇지 않으면 AI를 사용하여 재생성해야 합니다(API 크레딧 비용 발생).

내 프레임워크가 아직 지원되지 않으면 어떻게 하나요? 새 컴파일러는 현재 Next.js와 Vite를 지원합니다. 다른 프레임워크는 곧 지원될 예정입니다. 기존 컴파일러를 계속 사용하거나 프레임워크 지원에 기여하세요.

마이그레이션에 얼마나 걸리나요?

  • 간단한 프로젝트: 15-30분
  • 복잡한 프로젝트: 1-2시간
  • 대부분의 시간은 번역 테스트 및 검증에 소요됩니다

지금 마이그레이션해야 하나요, 아니면 기다려야 하나요? 다음의 경우 마이그레이션하세요:

  • 새로운 기능이 필요한 경우(빌드 모드, 오버라이드, 커스텀 리졸버)
  • 새 프로젝트를 시작하는 경우
  • 더 나은 개발자 경험을 원하는 경우

다음의 경우 기다리세요:

  • 기존 컴파일러로 프로젝트가 잘 작동하는 경우
  • 새 컴파일러에서 아직 지원되지 않는 프레임워크가 필요한 경우

다음 단계