多言語対応がめんどくさいからChatGPTにやらせてみた(1日クッキング)
はじめに
Next.js で構築しているサービスを多言語対応させたくなった。
でも、めんどくさい事はやりたくないし、翻訳精度も高精度がいい。
CSR にも SSG にも対応させたい。
そうだ、ChatGPT に任せてみよう。
目標
こんな感じで、決められたコンポーネントでテキストを包むだけで、自動的にChatGPTに翻訳してほしい
const Test = () => {
return <GlobalText>快適にご利用いただくために</GlobalText>
}
多言語対応辞書生成モジュール を作成する感じになりそう
辞書さえ生成できればあとはどうとでもなるからね
JSX(TSX)の探索
glob で対象ファイルを検索
const paths = await glob(`${translateTargetDir}/**/*.+(tsx|jsx)`);
@babel/parser と @babel/traverse で、JSXを解析しつつ
"GlobalText" コンポーネントを探し、その中のテキストだけ取ってくる
const targetTexts: string[] = [];
paths.forEach(file => {
const content = fs.readFileSync(file, 'utf-8');
const ast = parser.parse(content, {
sourceType: 'module',
plugins: ['jsx', 'typescript']
});
traverse(ast, {
JSXElement(path) {
if (
'name' in path.node.openingElement.name &&
path.node.openingElement.name.name === 'GlobalText'
) {
path.node.children.forEach(child => {
if (child.type === 'JSXText') {
const text = normalizeString(child.value);
targetTexts.push(text);
console.info('found text: ', text, text.length);
}
});
}
}
});
});
翻訳
取得した文字列の配列を、自前で構築した ChatGPT サーバーに投げ、返却された翻訳結果でjsonファイルを作成する
ちなみに、ChatGPT のモデルは 'gpt-3.5-turbo' を使うと、こちらが希望する形式で返却してくれないことが多々あったので、gpt-4 turbo(gpt-4-1106-preview) を使用した。
req
{
"text": "[テストです, こんにちは]"
}
res
{
"content": "{\"en\": [\"It's a test\", \"Hello\"], \"ko\": [\"테스트입니다\", \"안녕하세요\"]}",
"usage": {
"prompt_tokens": 319,
"completion_tokens": 28,
"total_tokens": 347
}
}
作成するjson ファイルの形式はこんな感じ
export interface Output {
[hash: string]: {[lang: string]: string};
}
ポイントは、"GlobalText" コンポーネントで括った、「翻訳元の日本語」を sha-256 でハッシュ化して、json のキーにすること。
辞書ファイルとして書き込み
const writeOutputs = (globalTextMap: Output, outputTargetDir: string) => {
const globalTextMapCacheOutput = `${JSON.stringify(globalTextMap)}`;
fs.writeFileSync(
`${outputTargetDir}/${CACHE_FILENAME}`,
globalTextMapCacheOutput,
'utf8'
);
};
こんな感じの出力になる
{
"f1b04f77514c350cc6d69ff2847e1c211790e470ff91f34bf0a3226ad5e7e464": {
"en": "For your comfortable use",
"ko": "편안한 이용을 위하여"
},
"f68d602db234c10114afd38158e3e16ae2c276887abbdac716096b39ce0c110e": {
"en": "There is a possibility that Bluetooth earphones may not work properly",
"ko": "블루투스 이어폰은 제대로 들리지 않을 수 있습니다"
},
"40e1fe4392655a130f715a52fd8a66f738db8d6007aa9ca93f483a2cfd85e359": {
"en": "We recommend closing other tabs and background apps",
"ko": "다른 탭이나 백그라운드 앱을 종료하는 것이 좋습니다"
}
etc .......
}
基本的に必要な事はこれだけ
あとはモジュール化して 別プロジェクトで yarn add でインポートができる様にして、shell で コマンド実行すれば、辞書ファイルの生成ができる様にした
npm-scripts
{
"scripts": {
"gtb": "create-global-txt 'https://xxxxxx' './src/constants/globalTxtBuilder/outputs' './src'",
"build:gtb": "npm run gtb && NEXT_PUBLIC_ENV=prd NEXT_PUBLIC_BUILD_LANG=en next build"
}
}
自社サービスで確かめてみる
このモーダルのテキスト達を "GlobalText" コンポーネントで囲ってみる
おお、ちゃんと翻訳された
あとがき
ChatGPT すげえ
1日でこんなのができる時代になったんだね
今回作った多言語対応辞書生成モジュールはこちら
Discussion