Angular PWA 배포 시 현지화(Localization) 작업 속도 높이기
요약
Angular PWA 개발 시 현지화(Localization) 작업 속도를 높이기 위한 자동화 워크플로우를 소개합니다. AppTranslation CLI를 활용하여 JSON, XML, HTML 리소스를 일괄 번역하는 방법을 다룹니다.
핵심 포인트
- AppTranslation CLI를 통한 UI 텍스트 및 리소스 파일 번역 자동화
- JSONPath 및 XPath를 활용한 정밀한 번역 대상 선택
- Angular 기반 PWA 환경에서의 효율적인 다국어 앱 빌드 전략
- 배경 (Background)
- 참고 문헌 (References)
- 앱 UI (App UI)
- 기술적 세부 사항 설명 (Technical Details Explained)
- 도움말 HTML 콘텐츠 (Help HTML Content)
- 기술적 세부 사항 설명 (Technical Details Explained)
- 테스트 콘텐츠 (Test Contents)
- 기술적 세부 사항 설명 (Technical Details Explained)
- manifest.webmanifest
- 기술적 세부 사항 설명 (Technical Details Explained)
- 다국어 앱 빌드 (Build for Multilingual App)
- 기술적 세부 사항 설명 (Technical Details Explained)
- 요약 (Summary)
- AI 정보 (About AI)
배경 (Background)
개발 및 배포 과정에서 높은 생산성을 유지하는 것을 즐기는 게으른 소프트웨어 개발자로서, 저는 이미 유명 벤더와 오픈 소스 커뮤니티에서 제공하는 수많은 도구 외에도 저만의 워크플로우를 위한 자동화 솔루션을 구축하며 수년을 보냈습니다.
최근에는 애플리케이션 리소스(UI 텍스트, XLIFF와 같은 현지화 리소스 파일)의 일괄 번역을 자동화하기 위해 설계된 개발자 중심의 CLI 도구 및 라이브러리 모음인 AppTranslation CLI를 다음과 같은 새로운 범용 메타 형식으로 확장했습니다:
- JSONPath로 선택된 JSON 텍스트 노드.
- XPath로 선택된 XML 텍스트 노드.
- XPath로 선택된 HTML 문서 또는 노드.
정적 사이트 PWA인 Ishihara Color Blind Test라는 실제 사례를 통해 이러한 도구들을 어떻게 사용하는지 살펴보겠습니다.
개발 플랫폼:
- Angular 21+
- Angular Material Components.
- Google Translate v2/3 또는 MS Translator와 함께 사용되는 "AppTranslation CLI" (최신 릴리스).
이 글은 여러분이 이미 Angular 2+, React 또는 이와 유사한 기술로 SPA/PWA를 구축하는 데 익숙하며, 국제화 (internationalization) 및 현지화 (localization)를 이해하고 있다고 가정합니다.
여기서의 초점은 국제화가 이미 잘 설계되고 구현되었다는 가정하에, PWA를 배포할 때 수반되는 현지화 작업의 속도를 높이는 데 있습니다.
참고 문헌 (References)
- Angular Internationalization (i18n)
- Angular internationalization and localization: A complete guide
- AppTranslation CLI
App UI
Angular와 같은 프레임워크는 XLIFF와 같은 번역 리소스를 통해 국제화 (Internationalization, i18n)에 대한 내장 지원을 제공합니다.
워크플로우 (Workflow):
ng extract-i18n을 통해 XLIFF 파일 업데이트
↓
MsTranslatorXliff.exe를 사용하여 업데이트된 XLIFF 노드 번역
대부분의 현지화 (Localization, l10n) 작업은 ng build 이전에 수행됩니다:
- Angular 코드에서 현지화된 문자열을 변경할 때마다,
ng extract-i18n을 실행하여 "Src/color-blind-app/src/locales"에 있는 XLF 파일들을 업데이트한 다음, "myApp/src/locales"에서 "TranslateLocales.ps1"을 실행합니다. - 새로운 지원 로케일 (Locale)을 추가할 때마다, "projects/myApp/i18n/locales" 및 "myApp/extract-i18n/options/targetFiles" 아래의 "angular.json"을 업데이트합니다. 그 다음
ng extract-i18n을 실행하고 이어서node generate-lang-codes.js를 실행합니다. 이 과정은 다른 스크립트들("src/app/locales.auto.ts", "src/app/locales.auto.html", "locales.auto.ps1")에서 사용되는 로케일 배열을 재생성합니다. - 마지막으로, "TranslateLocales.ps1"을 실행하여 모든 XLIFF 파일을 번역합니다.
기술적 세부 사항 설명 (Technical Details Explained)
"TranslateLocales.ps1"
Set-Location $PSScriptRoot
$commandPath = 'C:/VsProjects/OpenSource/Translation/Release/All_Win/GoogleTranslateXliff.exe'
$apiKey = 'YourGoogleTranslateV2ApiKey'
...
"locales.auto.ps1"은 "generate-lang-codes.js"에 의해 생성됩니다:
$names = @("en", "ar", "de", "es", "fr", "hi", "it", "ja", "ko", "pt", "ru", "tr", "vi", "zh-Hans", "zh-Hant")
return $names
Ishihara 색맹 테스트 (Ishihara Color Blind Test)의 핵심적인 UX 기능 중 하나는, 사용자가 기본 시작 URL인 https://appHost/en을 통해 앱을 처음 실행할 때, 앱이 시스템/브라우저의 기본 언어를 감지하여 해당 언어로 UI와 콘텐츠를 제공한다는 점입니다. 예를 들어, 기본 언어가 "fr-CA"라면 앱은 https://appHost/fr로 리다이렉트 (redirect)됩니다. 첫 실행 이후에는 사용자가 이 기본 설정을 변경하여 지원되는 모든 로케일 (locale)로 전환할 수 있습니다.
이 때문에 앱은 처음에 실행되는 Angular 앱의 부트스트랩 (bootstrap) 이전에 클라이언트 측 리다이렉트 (client-side redirection)를 수행해야 하며, 사용자가 마지막으로 선택한 로케일을 로드해야 합니다.
부트스트랩 전후로 리다이렉트를 올바르게 처리하기 위해, 앱 코드는 어떤 로케일들이 지원되는지 알고 있어야 합니다. 목록을 하드코딩 (hard-coding) 하는 대신, src/app/locales.auto.ts 파일이 "angular.json"으로부터 "generate-lang-codes.js"에 의해 생성되며, 이 파일이 지원되는 로케일에 대한 단일 진실 공급원 (single source of truth) 역할을 합니다.
"src/app/locales.auto.ts":
export const SUPPORTED_LOCALES : string[] = [
"en",
"ar",
...
"generate-lang-codes.js":
// angular.json에 선언된 언어 코드를 생성합니다.
// src/app/locales.auto.ts, src/app/locales.auto.html 및 locales.auto.ps1을 업데이트하려면 `node generate-lang-codes.js`를 실행하세요.
const fs = require('fs');
...
도움말 HTML 콘텐츠 (Help HTML Content)
도움말 콘텐츠는 동일한 서버에 호스팅되지만 빌드 자산 (build assets) 의 일부는 아닌 독립적인 HTML 파일들로 구성됩니다. 이 파일들은 "public/help" 아래에 위치하며, 앱은 필요할 때 관련 HTML 파일을 로드합니다.
도움말 콘텐츠가 변경될 때마다 "TranslateHelpHtml.ps1"을 실행하여 "public/help"에 있는 파일들을 "metaLocalized" 폴더로 번역합니다. 그 후 "buildParams.ps1"의 빌드 후 처리 (post-build handling) 단계에서 번역된 HTML 파일들을 각 현지화된 빌드의 해당 도움말 폴더로 복사합니다.
기술적 세부 사항 설명
TranslateHelpHtml.ps1:
# HTML 데이터 아티팩트(artifacts)를 번역합니다.
Set-Location $PSScriptRoot
$commandPath = 'C:/VsProjects/OpenSource/Translation/Release/All_Win/GoogleTranslateHtml.exe'
...
힌트:
$locales에 "en"이 포함될 수 있음에 유의하세요. 이 경우, 대상 언어와 소스 언어가 일치하므로GoogleTranslateHtml.exe는 번역 없이 파일을 단순히 복사합니다. 이는 대상 파일명에 확장자 전의 ".$lang" 접미사가 필요하지 않을 때 유용합니다.
현지화된 스페인어 빌드에서 생성된 스페인어 HTML 도움말 콘텐츠는 다음과 같습니다.
테스트 콘텐츠
앱은 색맹 테스트 콘텐츠를 위해 "index.json"을 로드합니다:
{
"$schema": "https://raw.githubusercontent.com/zijianhuang/schemas/refs/heads/main/json/AllColorBlindTestsSchema.json",
"title": "Ishihara Plates (2026)",
...
"index.json" 내의 몇몇 노드(nodes)는 번역이 필요합니다. 이를 처리하려면 "TranslatePlatesIndexJson.ps1"을 실행하세요.
예를 들어, 스페인어로 현지화된 index.json은 다음과 같습니다.
기술적 세부 사항 설명
TranslatePlatesIndexJson.ps1:
Set-Location $PSScriptRoot
$commandPath = 'C:/VsProjects/OpenSource/Translation/Release/All_Win/GoogleTranslateJson.exe'
$apiKey = 'YourGoogleTranslateV2ApiKey'
...
manifest.webmanifest
이 파일의 몇몇 노드(nodes)는 번역이 필요하며, 각 현지화된 빌드에 맞춰 "start_url"을 조정해야 합니다. 두 작업을 모두 처리하려면 "TranslateManifest.ps1"을 실행하세요.
예를 들어,
기술적 세부 사항 설명
TranslateManifest.ps1:
# metaLocalized 폴더에 저장된 각 현지화된 앱의 매니페스트(manifest) 파일을 번역합니다.
Set-Location $PSScriptRoot
$commandPath = 'C:/VsProjects/OpenSource/Translation/Release/All_Win/GoogleTranslateJson.exe'
...
adjustManifest.js:
// 각 로케일(locale)에 따라 manifest의 lang, scope, start_url을 변경하며, metaLocalized 폴더에 저장됩니다.
// 일반적으로 TranslateManifest.ps1 내부에서 호출됩니다.
// Claude.ai에 의해 제작되었습니다.
...
다국어 앱을 위한 빌드 (Build for Multilingual App)
때로는 프론트엔드 UI만 현지화(Localization)가 필요한 경우가 있습니다. 반면, 이 글의 샘플 앱과 같이 몇 가지 추가적인 기술적 및 기능적 데이터도 현지화가 필요한 경우도 있습니다.
개발 중에는 현지화된 빌드를 포함하지 않고 로컬 머신에서 개발 빌드를 테스트하기 위해, 단순히 ./buildParams.ps1을 실행하면 됩니다.
프로덕션 빌드(production build)를 로컬에서 테스트하려면, "buildProdEn.ps1"을 실행하세요:
./buildParams.ps1 -buildConfig "production" -outputPath "../ngdist/prodEn"
프로덕션 빌드를 로컬에서 테스트하거나 "https://cbt.fonlow.org"에 배포하려면, 빌드 스크립트 "buildProdLocalize.ps1"을 사용하세요:
Set-Location $PSScriptRoot
$outputPath="../ngdist/prodLocalize"
./buildParams.ps1 -buildConfig "production" -baseHref "/" -outputPath $outputPath -localize $true
...
"https://zijianhuang.github.io/cbt"에 배포하려면, 빌드 스크립트 "buildProdGitHubPages.ps1"을 사용하세요:
Set-Location $PSScriptRoot
$outputPath="../ngdist/prodGHP"
$githubRepo="cbt"
...
기술적 세부 사항 설명 (Technical Details Explained)
위의 모든 빌드 스크립트의 핵심은 "buildParams.ps1"입니다:
<#
.SYNOPSIS
개발을 위한 기본 빌드 스크립트입니다. 매개변수(parameters)를 통해 다른 빌드 프로필 및 다양한 배포 대상에 사용할 수 있습니다.
...
보시다시피, 빌드 전 처리(pre-build processing) 과정은 다음을 포함합니다:
- 타임스탬프 JS 파일 생성.
- "locales.auto.ts" 생성.
두 파일 모두 ng build 과정 중에 JS 번들(bundle)의 일부가 됩니다.
빌드 후 처리(post-build processing)는 번역된 리소스들을 복사하고, ng build가 처리할 수 있는 범위를 벗어나는 다양한 기술적 요구 사항에 맞춰 일부 메타데이터와 설정을 조정합니다.
요약 (Summary)
소규모 소프트웨어 개발 업체에서는 개발자들이 직접 현지화 (Localization) 작업을 수행해야 하는 경우가 많습니다. 특히 앱에 현지화된 UI 텍스트뿐만 아니라 현지화된 데이터와 설정 (Config)이 함께 필요한 경우 더욱 그렇습니다. 적절한 CLI 도구와 스크립트가 갖춰져 있다면, 이러한 작업은 훨씬 적은 골칫거리와 함께 속도를 크게 높일 수 있습니다.
AI에 대하여
오늘날 기계 번역 (Machine translation)은 LLM에 크게 의존하고 있으며, Claude나 ChatGPT와 같은 저명한 AI 엔진들은 원칙적으로 AppTranslation CLI가 수행하는 모든 작업을 할 수 있습니다. 하지만 몇 가지 주의할 점이 있습니다.
- XLIFF나 XML과 같은 메타 형식을 분석하는 것은 많은 토큰 (Tokens)을 소모합니다. 특히 모델에게 무엇을 번역할지 지시하기 위해 필요한 프롬프트 (Prompts)까지 고려하면 더욱 그렇습니다.
- AI 엔진의 API를 사용하여 프롬프트를 스크립트로 작성할 수는 있지만, 메타 형식을 분석하고 번역을 수행하는 전체 프로세스는 AppTranslation CLI가 전용 번역 엔진을 직접 호출하는 것보다 훨씬 느려질 수 있습니다. 요컨대, 현지화 속도가 느려지고 예상치 못한 토큰 비용이 발생할 위험이 있습니다.
- AI의 메타 형식 분석은 프롬프트를 신중하게 제한하더라도 본질적으로 근사치이며 비결정론적 (Non-deterministic)입니다. 그 결과, 번역된 메타 데이터가 일부 잘못 처리될 수 있습니다.
그럼에도 불구하고, 저는 일회성 메타 형식을 즉석에서 번역할 때는 여전히 가끔 AI를 사용합니다. 하지만 이러한 필요성이 더 자주 발생함에 따라, 앞서 언급한 문제점들이 피부로 와닿기 시작했습니다. 그것이 제가 AppTranslation CLI가 XML, JSON, HTML을 지원하도록 구축하게 된 계기입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기