솔로 .NET 개발자를 위한 $0 로컬라이제이션 스택

발행: (2025년 12월 30일 오전 07:58 GMT+9)
11 min read
원문: Dev.to

Source: Dev.to

위에 제공된 텍스트가 없습니다. 번역하려는 본문을 제공해 주시면 한국어로 번역해 드리겠습니다.

문제

내 앱에 400개 이상의 문자열이 있었습니다. 최소한 그리스어와 영어, 가능하면 더 많은 언어에 대한 번역이 필요했습니다. 선택지는 다음과 같았습니다:

옵션비용속도
Lokalise$120/mo빠름
Phrase$25/mo빠름
Manual Google Translate$0복사‑붙여넣기 지옥 (시간 다소)
Hire translator$100+며칠

아이디어

당신의 자체 머신에서 번역 모델을 실행할 수 있다면 어떨까요? API 비용도 없고, 속도 제한도 없으며, 데이터가 컴퓨터를 떠나지 않습니다.

그것이 바로 제가 **LRM (Localization Resource Manager)**에 구현한 것입니다.

1️⃣ Ollama 설치 (로컬 LLM 런타임)

# Linux
curl -fsSL https://ollama.ai/install.sh | sh

# Windows / macOS – download from https://ollama.ai

2️⃣ 모델 가져오기

ollama pull llama3.2          # default
# or for better quality
ollama pull llama3.1:8b

3️⃣ Install LRM

# Linux (one‑liner)
curl -sSL https://raw.githubusercontent.com/nickprotop/LocalizationManager/main/install-lrm.sh | bash

# Or via APT (Ubuntu/Debian)
sudo add-apt-repository ppa:nickprotop/lrm-tool
sudo apt install lrm-standalone

# Windows / macOS – download from GitHub releases
# https://github.com/nickprotop/LocalizationManager/releases

그게 전부입니다. API 키도, 계정도, 신용카드도 필요 없습니다.

4️⃣ 번역

# Navigate to your project
cd MyApp/Resources

# Translate all missing keys to Spanish, French, German
lrm translate --only-missing --provider ollama --target-languages es,fr,de

LRM은 모든 .resx 파일을 찾아 누락된 번역을 식별하고 로컬 LLM을 사용해 채워줍니다.

  • 400개 이상의 키 × 3개 언어 = 1,200개 이상의 번역
  • 비용 제로
  • 10분 이내

GPU가 없나요? 무료 온라인 제공자를 사용하세요 (여전히 $0)

lrm translate --only-missing --provider mymemory --target-languages es,fr,de
# 5,000 characters/day free – enough for most projects
lrm translate --only-missing --provider lingva --target-languages es,fr,de
# Uses an open‑source proxy to Google Translate – no API key needed

이탈리아어 추가 – 실제 예제

# Add a new language file
lrm add-language --culture it

# Check what’s missing
lrm stats
                         Localization Statistics
┌───────────────┬────────────┬───────────┬───────┬──────────┬───────────┐
│ Language      │ Total Keys │ Completed │ Empty │ Coverage │ File Size │
├───────────────┼────────────┼───────────┼───────┼──────────┼───────────┤
│ Default       │ 12         │ 12        │ 0     │ 100.0%   │ 1.8 KB    │
│ Deutsch (de)  │ 12         │ 5         │ 7     │ 41.7%    │ 1.6 KB    │
│ français (fr)│ 12         │ 7         │ 5     │ 58.3%    │ 1.7 KB    │
│ italiano (it)│ 12         │ 0         │ 12    │ 0.0%     │ 1.6 KB    │
└───────────────┴────────────┴───────────┴───────┴──────────┴───────────┘

이탈리아어는 **0 %**입니다 – 해결해 봅시다:

lrm translate --only-missing --provider ollama --target-languages it
╭─────────────────────┬──────────┬─────────────────────────────────────┬────────╮
│ Key                 │ Language │ Translation                         │ Status │
├─────────────────────┼──────────┼─────────────────────────────────────┼────────┤
│ AppTitle            │ it       │ Responsabile dello studio medico    │ ✓      │
│ WelcomeMessage      │ it       │ Eccoci di nuovo, {0}!               │ ✓      │
│ LoginButton         │ it       │ Accedi                              │ ✓      │
│ LogoutButton        │ it       │ Disconnettere                       │ ✓      │
│ SaveButton          │ it       │ Salva                               │ ✓      │
│ CancelButton        │ it       │ Cancella                            │ ✓      │
│ DeleteConfirmation  │ it       │ Sei sicuro di voler eliminare...    │ ✓      │
│ ErrorOccurred       │ it       │ Si è verificato un errore...        │ ✓      │
│ PatientName         │ it       │ Nome del paziente                   │ ✓      │
│ AppointmentDate     │ it       │ Data prenotazione                   │ ✓      │
│ NoResultsFound      │ it       │ Nessun risultato trovato            │ ✓      │
│ SearchPlaceholder   │ it       │ Cerca pazienti                      │ ✓      │
╰─────────────────────┴──────────┴─────────────────────────────────────┴────────╯

12개 중 12개 항목이 몇 초 만에 번역되었습니다. 완료.

CLI는 색상 출력을 사용합니다 – 누락된 번역은 빨간색으로, 완료된 번역은 초록색으로 표시됩니다.

“품질이 충분히 좋은가요?”

내 앱 문자열에 대해 Ollama (llama3.2) vs Google Translate vs DeepL을 비교했습니다:

ProviderQualityCostSpeed
DeepL훌륭함$20/mo빠름
Google매우 좋음Pay‑per‑use빠름
Ollama (llama3.2)좋음$0보통
MyMemory좋음$0빠름
  • UI 문자열 예: “Save”, “Cancel”, “Error occurred”? Ollama는 충분히 좋습니다.
  • 마케팅 카피나 법률 텍스트? DeepL에 비용을 지불하는 것이 좋습니다.
  • 앱 현지화의 90 %? 무료로 충분합니다.

번역을 넘어 – 검증 및 정리

번역 작업이 완료된 후, LRM은 검증 기능을 포함하도록 확장되었습니다:

lrm validate
⚠ Validation found 12 issue(s)

                                  Empty Values
┌──────────┬───────────────────────────────────────────────────────────────────┐
│ Language │ Empty Keys                                                        │
├──────────┼───────────────────────────────────────────────────────────────────┤
│ de       │ CancelButton, DeleteConfirmation, ErrorOccurred, PatientName…   │
│ fr       │ ErrorOccurred, PatientName, AppointmentDate, NoResultsFound…    │
└──────────┴───────────────────────────────────────────────────────────────────┘

LRM은 C#, Razor, XAML 파일을 스캔하여 다음을 찾습니다:

  • Missing keys – 코드에서는 사용되지만 .resx에 정의되지 않은 키(실행 시 오류가 발생할 수 있음)
  • Unused keys.resx에 정의되어 있지만 사용되지 않은 키(불필요한 부피 증가)

그런 다음 단일 명령으로 정리할 수 있습니다:

lrm prune-unused

TL;DR – 전체 워크플로우

# 1️⃣ Install Ollama
curl -fsSL https://ollama.ai/install.sh | sh

# 2️⃣ Pull a model
ollama pull llama3.2

# 3️⃣ Install LRM
curl -sSL https://raw.githubusercontent.com/nickprotop/LocalizationManager/main/install-lrm.sh | bash

# 4️⃣ Translate missing strings
cd MyApp/Resources
lrm translate --only-missing --provider ollama --target-languages es,fr,de,it

# 5️⃣ Validate & prune
lrm validate
lrm prune-unused

결과: $0 비용으로 5개 언어에 완전히 현지화된 .NET 앱을 10분 미만의 작업 시간으로 만들 수 있습니다. 🎉

sed in code (dead translations)

lrm scan --source-path ./src
✓ Scanned 3 files
Found 18 key references (16 unique keys)

Missing Keys (in code, not in .resx)
┌─────────────────────┬────────────┬───────────────────────────┐
│ Key                 │ References │ Locations                 │
├─────────────────────┼────────────┼───────────────────────────┤
│ AboutUs             │ 1          │ HomeController.cs:31      │
│ AppSubtitle         │ 1          │ HomeController.cs:22      │
│ CompanyDescription  │ 1          │ HomeController.cs:32      │
│ GetStarted          │ 1          │ Index.cshtml:9            │
│ OperationFailed     │ 1          │ NotificationService.cs:23 │
│ OperationSuccessful │ 1          │ NotificationService.cs:17 │
│ … and 7 more       │            │                           │
└─────────────────────┴────────────┴───────────────────────────┘

✗ Found 13 missing keys and 2 unused keys

13개의 키가 코드에 사용되었지만 .resx 파일에 존재하지 않습니다!
이는 런타임 오류를 일으킬 수 있습니다. 이제 사용자가 깨진 UI를 보기에 앞서 키를 추가할 수 있습니다.

대규모 프로젝트(실제 앱)에서는 반대 상황도 발견되었습니다:

lrm scan --source-path ./src
✓ Scanned 497 files
Found 607 key references (394 unique keys)

Unused Keys (in .resx, not in code)
┌────────────────────────────┬───────┐
│ Key                        │ Count │
├────────────────────────────┼───────┤
│ ActiveAdmissions           │ -     │
│ AdmissionCount             │ -     │
│ DailyAdmissions            │ -     │
│ LanguageAutoDetect         │ -     │
│ MarkAsComplete             │ -     │
│ … and 51 more              │       │
└────────────────────────────┴───────┘

✗ Found 0 missing keys and 56 unused keys

56개의 사용되지 않는(dead) 키를 정리할 수 있습니다.
불필요한 파일을 줄이고, 리소스 파일을 작게 유지할 수 있습니다.

인터랙티브 편집기 (TUI)

lrm edit

포맷 간 변환

lrm convert --from resx --to json

번역가용 내보내기

lrm export --format csv

지원되는 형식 (한 도구)

  • .resx – WPF, WinForms, ASP.NET
  • JSON – ASP.NET Core, Blazor
  • i18next – React, Vue, Angular
  • Android strings.xml
  • iOS .strings

모든 형식, 한 도구.

내 전체 현지화 워크플로우

  1. 새 영어 문자열을 일반적으로 앱에 추가합니다.

  2. 검증 (문제를 조기에 포착)

    lrm validate
  3. 누락된 키를 번역

    lrm translate --only-missing --provider ollama
  4. TUI에서 빠른 검토

    lrm edit
  5. 커밋

    git add Resources/
    git commit -m "Add translations"

총 소요 시간: 5 분 총 비용: $0.

오픈소스 프로젝트

  • 저장소:
  • 라이선스: MIT (원하는 대로 사용하세요)
  • 특징: 100 % 오프라인, 계정 없음, 추적 없음, 자체 호스팅 가능.

“앱을 번역해야 한다”는 작은 필요에서 시작했지만 점점 커졌습니다. CLI가 너무 잘 작동해서 기능을 계속 추가했고, 웹 UI, 클라우드 동기화, OTA 업데이트까지 만들었습니다. 이제는 완전한 플랫폼이 되었습니다.

클라우드가 성장하는 솔로 개발자에게 필요한 것을 추가합니다

기능설명
포맷에 구애받지 않음하나의 프로젝트가 RESX, JSON, i18next와 동기화됩니다
웹 편집기어디서든 번역을 편집, CLI 필요 없음
OTA 업데이트재배포 없이 번역 업데이트 (.NET 최초 OTA!)
GitHub 동기화레포와 양방향 동기화
번역 메모리이전 번역 재사용, API 비용 절감
용어집일관된 용어 사용 강제
번역가 초대번역가는 브라우저에서 편집하고, 당신은 검토 및 승인
무료 티어3개 프로젝트, 월 5 K 문자 – 사이드 프로젝트에 충분

CLI는 100 % 무료이며 오픈소스입니다. 클라우드는 선택 사항이며 원한다면 자체 호스팅이 가능합니다!

설치 (Linux)

curl -sSL https://raw.githubusercontent.com/nickprotop/LocalizationManager/main/install-lrm.sh | bash
ollama pull llama3.2

앱을 무료로 번역하기

cd YourProject/Resources
lrm translate --only-missing --provider ollama --target-languages es,fr,de,it,pt

완료. $0, 5 분.

도움이 필요하신가요?

  • GitHub에 이슈를 열어 주세요.
  • Reddit에서 저를 찾아 주세요.

이 내용이 도움이 되었다면, GitHub 스타를 눌러 다른 사람들에게 알리는 데 도움이 됩니다.

Tags: dotnet, localization, i18n, translation, ollama, llm, open-source, csharp, blazor, aspnetcore

Back to Blog

관련 글

더 보기 »