В текущем мире очень многие сайты имеют поддержку многих языков, в большинстве случаев это происходит с помощью i18n npm пакета. Чаще всего переводы хранятся в .js, .json файлах и очень часто есть языки для которых в компании нет переводчика, либо же он не предполагался в целом, и в таком случае приходит на помощь разработчик с Google Translate. И вот однажды я столкнулся с тем, что на проекте оказалось очень много текстов и все их нужно было переводить вручную, что занимало достаточно много времени и я задумался о том, как это можно автоматизировать.
Моя идея была в том, чтобы написать функцию, в которую можно было бы передать языковой код и json объект с текстом на исходном языке, а на выходе получить переведенный json/js file. С помощью этой функции я мог бы в ci/cd Pipeline переводить все текста на проекте, в исходных текстах которых были изменения, либо же следить за текстами в рантайме и на лету переводить их.
И я нашел два относительно простых метода, для того чтобы это сделать, один из них платный, другой бесплатный.
Способ №1
Я думаю у многих в компании сейчас активно используются всякие ИИ чат-боты в духе chatgpt и тд, и у многих из них есть api, в которых вы можете получить api key и с помощью него отправлять ему запросы. В моем случае я использовал chatgpt от OpenAI и у них есть специальный npm пакет для node js — тык, с помощью которого можно взаимодействовать с chat ботом, вот и тут я подключаю эту библиотеку и отправляю запрос со следующим prompt — translate object values to ${language} ${JSON.stringify(text)}, где language — языковой код нужного вам языка(языковые коды — тык), text — наш объект с переводами.
translate.js
const { Configuration, OpenAIApi } = require('openai'); const fs = require('fs'); const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY, }); const openai = new OpenAIApi(configuration); async function getTranslation(languageCode, text) { try { const result = await openai.createChatCompletion({ model: 'gpt-3.5-turbo', messages: [{ role: 'user', content: `translate object values to ${languageCode} ${JSON.stringify(text)}` }], }); return result.data.choices[0].message.content; } catch (error) { console.error(error); return null; } }; getTranslation('zh', { label: 'Article about translation', title: 'Easy way to implement i18n', description: 'Try to translate this description', }).then((result) => { fs.writeFileSync('cn.json', result); }); module.exports = getTranslation;
Как итог мы получаем переведенный json и можем записать его в нужный нам файл.
Способ №2
Абсолютно бесплатный метод, в котором я использую другую библиотеку — тык, совершенно случайно наткнулся на эту библиотеку на GitHub и решил попробовать ее, по мне работает неплохо — она использует Google Translate. Здесь я реализую аналогичную функцию, за исключением того, что тут я не могу передать весь объект для перевода, поэтому здесь перебирается все значения в объекте и по очереди переводятся.
translate.js
const translate = require('node-google-translate-skidz'); const fs = require('fs'); async function getTranslation(languageCode, text) { const getTranslate = async (value) => { const t = await translate({ text: value, source: 'en', target: languageCode, }); return t.translation; }; const processObject = async (obj) => { for (const key in obj) { if (obj.hasOwnProperty(key)) { const value = obj[key]; if (typeof value === 'object') { await processObject(value); } else { try { const processedValue = value ? await getTranslate(value) : value; obj[key] = processedValue; } catch (error) { console.error(error); obj[key] = value; } } } } }; const copy = JSON.parse(JSON.stringify(text)); await processObject(copy); return JSON.stringify(copy, null, 2); }; getTranslation('zh', { label: 'Article about translation', title: 'Easy way to implement i18n', description: 'Try to translate this description', }).then((result) => { fs.writeFileSync('cn.json', result); }); module.exports = getTranslation;
На выходе также получаем переведенный json файл.
Итого
У меня получился вот такой скрипт, в который я могу прокинуть файл откуда прочитать перевод и куда его записать, также здесь я сделал проверку на то, .json файл это или .js и написал парсер для этого:
const fs = require('fs'); const getTranslation = require('./translate.js'); // .js file имеет вид export const ${languageCode} = { ... }, соответственно для того, чтобы получить контент можно взять все в {} и с помощью eval(я знаю что eval это плохо) преобразовать это в js объект const parseScriptFile = (filePath) => { const fileData = fs.readFileSync(filePath, 'utf-8'); const jsonStartIndex = fileData.indexOf('{'); const jsonEndIndex = fileData.lastIndexOf('}'); const jsonObjectString = fileData.slice(jsonStartIndex, jsonEndIndex + 1); const obj = eval(`(${jsonObjectString})`); return obj; }; const languageCode = 'zh'; const filePath = './en.js'; const destinationFilePath = './zh.js'; // Проверяю .js это файл или .json и по разному их обрабатываю const text = filePath.includes('.json') ? require(filePath) : parseScriptFile(filePath); getTranslation(languageCode, text).then((res) => { if (filePath.includes('.json')) { fs.writeFileSync(destinationFilePath, JSON.stringify(res, null, 2)); } else { fs.writeFileSync(destinationFilePath, `export const ${languageCode} = ${JSON.stringify(res, null, 2)}`); } });
Далее вы можете пропатчить эти скрипты в зависимости от ваших потребностей и получить автоматизированные и удобные переводы во Frontend.
Наслаждайтесь 🙂
Если статья показалась вам интересной, то у меня есть Тг-канал, где я пишу про новые технологии во фронте, делюсь хорошими книжками и интересными статьями других авторов.
ссылка на оригинал статьи https://habr.com/ru/articles/751366/
Добавить комментарий