i18n을 위한 번역값 관리 자동화

creatrip-sohee
creatrip
Published in
7 min readApr 15, 2024

안녕하세요. 크리에이트립(Creatrip)에서 프론트엔드 개발을 하고 있는 정소희라고 합니다.

어떤 내용이 흥미로울지 고민하다가 글로벌 서비스를 제공한다면 피할 수 없는 i18n, 그리고 자동화에 관련된 주제를 가져왔습니다.

이번 글의 주제는 “i18n을 위한 번역값 관리 자동화”입니다.

i18n이 뭔가요?

18n은 국제화(internationalization)를 뜻하는 말로, 제품이나 서비스를 모든 언어권에서 사용할 수 있도록 설계하고 개발하는 것을 말합니다.

i18n에는 여러 가지 항목들이 있는데, 오늘은 그 중에서도 “언어(문자)”에 대해 이야기 하려고 합니다.

크리에이트립 유저 페이지에서는 다양한 텍스트들을 8개의 언어로 지원하고 있습니다. 유저는 본인이 선택한 언어에 따라 의미에 맞는 텍스트들을 볼 수 있습니다.

english
japanese

타 부서에서 담당하는 번역값이 업데이트 되면, 완료된 번역값은 구글 스프레드시트를 통해 개발팀에 전달됩니다.

번역값 관리가 자동화되기 전에는 구글 스프레드시트에 정리된 번역값을 수동으로 개발 프로젝트 내 JSON 파일로 옮겨야 했습니다.

이렇게 수동으로 값을 업데이트 하는 방식은 번역값 변경사항에 대한 지속적인 모니터링으로 인한 피로감, 개발자 리소스의 불필요한 낭비, 그리고 인적 오류의 발생 가능성 등의 문제점을 갖고 있었습니다.

이런 단점들은 팀의 생산성과 제품의 품질에 영향을 미치므로, 자동화를 진행하며 다음과 같은 목표를 달성할 수 있을거라 생각했습니다.

  • 번역값 변경 누락 등 휴먼 에러 제거
  • 개발자 리소스 최소화
  • i18n을 사용한 개발 작업의 효율성 증대

자동화 작업은 단계적으로 고도화되었습니다.

1단계 : JSON 파일 업데이트 스크립트 작성

googleapis를 이용해 구글 스프레드시트에 등록된 번역 값을 로드하는 스크립트를 작성했습니다. 해당 스크립트를 실행할 때마다 구글 스프레드시트에서 데이터를 받아와 원하는 형식으로 JSON 파일을 구성합니다.

// 구글 스프레드시트 데이터를 로드하는 스크립트

const jwt = new google.auth.JWT({ // jwt 받아오기
email,
key,
scopes,
});

jwt.authorize(async (error) => { // jwt 인증 확인
if (error) {
console.error(error);
return;
}
await readSheet(jwt);
})

const readSheet = async (jwt: JWT) => { // 구글 스프레드 시트 읽어오기
const sheets = google.sheets({ version: 'v4', auth: jwt });
...데이터 형식에 맞게 가공
}

이제 단 한 줄의 명령어로 구글 스프레드 시트의 데이터를 자동으로 온전히 가져올 수 있게 되었습니다!

하지만 아직 불편함이 남아있습니다. 다수의 개발자가 각자의 로컬 환경에서 번역 JSON 파일을 업데이트 한다면, 업데이트 시기에 따라 번역값의 conflict가 발생할 수 있습니다. 또한, PR의 file change에 번역 값 변경이 포함되어 코드 리뷰시 불필요한 컨텍스트가 추가됩니다. 마지막으로 같은 번역 값에 대한 업데이트 리소스를 모든 개발자가 각자 사용해야 합니다.

2단계 : Github Workflow scheduler를 이용해 원격저장소에 변경 사항 반영

위 불편함들을 해소하기 위해 원격 저장소에 번역 값을 주기적으로 업데이트하고 개발자 각각이 저장소에 존재하는 최신 번역값을 의존하도록 할 수 있습니다.

원격 저장소에 번역 값을 최신화 하는 귀찮은 일은 봇에게 맡겨버립시다.

먼저 git workflow를 작성해 줍니다. 그리고 scheduler를 사용해 특정 시간마다 해당 workflow가 실행되도록 세팅 후, workflow 내에서 JSON 파일을 업데이트하는 스크립트를 실행하도록 만들어줍니다.

file change가 존재하면 PR을 생성하고, 존재하지 않으면 작업을 마무리합니다.

(사용 액션 : https://github.com/peter-evans/create-pull-request)

on:
workflow_dispatch:
schedule:
- cron: ... # 스케쥴링할 시간 설정

jobs:
create-pull-request:
runs-on: ubuntu-latest
steps:
...
- name: i18n Data 로드
run: npm run {스크립트_이름}

- name: Pull Request 생성
id: create-pull-request
uses: peter-evans/create-pull-request@v4 # file change 존재 시 PR 생성
with:
...
...

이제 직접 로컬 환경에서 스크립트를 실행해서 변경 사항을 원격 저장소에 반영해 주지 않아도 됩니다. 단순히 주기적으로 업데이트된 원격 저장소의 번역 값을 pull 해서 사용하면 됩니다!

3단계 : Github Workflow + Slack, Google Spreadsheet Apps Script + Slack 알림 연동

흠.. 조금 더 간편해질 순 없을까요?

PR이 생성될 때 사내 메신저로 알림을 보내서 PR이 생성되었는지 직접 github를 기웃거리지 않아도 변역 값의 변경을 알 수 있도록 해보겠습니다.

- name: i18n PR 생성 Slack 알림
if: ${{ success() && steps.create-pull-request.outputs.pull-request-operation == 'created' }}
uses: ./.github/actions/send-slack-message
with:
token: ${{ TOKEN }}
channel: {채널코드}
message: "i18n PR이 생성되었습니다."
link: ${{ steps.create-pull-request.outputs.pull-request-url }} //생성된 PR의 링크
name: "i18n PR 생성 알리미"

마지막으로 개발 팀 외의 구성원도 번역 시트의 변경사항을 인지할 수 있게 구글 Apps Script Trigger도 이용해봅시다. 시트의 변경을 감지할 목적으로 onEdit을 사용해줍니다.

function onEdit(e) {
...
UrlFetchApp.fetch(SLACK_WEBHOOK_POST_URL, {
method: "post",
payload: JSON.stringify({...})
});
}

위 두 연동 작업으로 개발자 뿐만 아니라 모든 구성원들이 번역 값의 변경을 빠르게 확인할 수 있게 되었습니다!

더불어

미처 담지는 못했지만, 이후 저희 팀은 더 높은 효율성을 위해서 github workflow에 번역 값 데이터에 대한 검증들을 추가했습니다. 이를 통해 더욱 안전성 있는 번역 값 관리 시스템을 구축할 수 있었습니다.

  • 사용되지 않는 번역 값 확인
  • 동적 파라미터 키값에 대한 휴먼 에러 감지
  • 프로덕트에서 사용되고 있는 번역 key가 누락되지 않도록 테스트

마치며

업무에서 리소스는 굉장히 중요한 자원입니다. 이 자원들을 불필요한 곳에 낭비하지 않고 효율적으로 사용할 수 있도록 하는 자동화 작업들은 매우 소중합니다.

아주 작고 간단한 작업일지라도 자동화를 통해 팀원들의 리소스를 확보 할 수 있다면 그 작업은 아주 멋지고 훌륭한 작업이 아닐까요?

앞으로도 생산성 향상을 위해 노력해야겠습니다. 우리의 코드 한 줄은 매우 소중하니까요!

--

--