babel-plugin-react-intl: извлекает строки в один файл

В настоящее время при использовании babel-plugin-react-intl для каждого компонента создается отдельный json с идентификатором, описанием и defaultMessage. Мне нужно создать только один json, который содержит один объект со всеми идентификаторами в качестве ключа и defaultMessage в качестве значения.

Текущая ситуация:

ComponentA.json

[
  {
    "id": "addEmoticonA",
    "description": "Add emoticon",
    "defaultMessage": "Insert Emoticon"
  },
  {
    "id": "addPhotoA",
    "description": "Add photo",
    "defaultMessage": "Insert photo"
  }
]

ComponentB.json

[
  {
    "id": "addEmoticonB",
    "description": "Add emoji",
    "defaultMessage": "Insert Emoji"
  },
  {
    "id": "addPhotoB",
    "description": "Add picture",
    "defaultMessage": "Insert picture"
  }
]

Что мне нужно для перевода.

final.json

{
  "addEmoticonA": "Insert Emoticon",
  "addPhotoA": "Insert photo",
  "addEmoticonB": "Insert Emoji",
  "addPhotoB": "Insert picture"
}

Есть ли способ выполнить эту задачу? Может быть, с помощью скрипта Python или чего-нибудь еще. т.е. сделать один файл json из разных файлов json. Или напрямую создать один файл json с помощью babel-plugin-react-intl


person iamsaksham    schedule 17.05.2016    source источник


Ответы (2)


Для этого существует менеджер переводов.

Или для индивидуального варианта см. Ниже


Приведенный ниже сценарий основан на этом скрипте просматривает сообщения перевода, созданные babel-plugin-react-intl, и создает файлы js, содержащие все сообщения от всех компонентов в формате json.

import fs from 'fs'
import {
  sync as globSync
}
from 'glob'
import {
  sync as mkdirpSync
}
from 'mkdirp'
import * as i18n from '../lib/i18n'

const MESSAGES_PATTERN = './_translations/**/*.json'
const LANG_DIR         = './_translations/lang/'
  // Ensure output folder exists
mkdirpSync(LANG_DIR)

// Aggregates the default messages that were extracted from the example app's
// React components via the React Intl Babel plugin. An error will be thrown if
// there are messages in different components that use the same `id`. The result
// is a flat collection of `id: message` pairs for the app's default locale.
let defaultMessages = globSync(MESSAGES_PATTERN)
  .map(filename => fs.readFileSync(filename, 'utf8'))
  .map(file => JSON.parse(file))
  .reduce((collection, descriptors) => {
    descriptors.forEach(({
      id, defaultMessage, description
    }) => {
      if (collection.hasOwnProperty(id))
        throw new Error(`Duplicate message id: ${id}`)

      collection[id] = {
        defaultMessage, description
      }
    })
    return collection
  }, {})

// Sort keys by name
const messageKeys = Object.keys(defaultMessages)
messageKeys.sort()
defaultMessages = messageKeys.reduce((acc, key) => {
  acc[key] = defaultMessages[key]
  return acc
}, {})

// Build the JSON document for the available languages
i18n.en = messageKeys.reduce((acc, key) => {
  acc[key] = defaultMessages[key].defaultMessage
  return acc
}, {})
Object.keys(i18n).forEach(lang => {
  const langDoc = i18n[lang]
  const units = Object.keys(defaultMessages).map((id) => [id, defaultMessages[id]]).reduce((collection, [id]) => {
    collection[id] = langDoc[id] || '';
    return collection;
  }, {});
  fs.writeFileSync(`${LANG_DIR}${lang}.json`, JSON.stringify(units, null, 2))
})

person slchap5    schedule 19.05.2016

Для агрегирования можно использовать babel-plugin-react-intl-extractor Ваши переводы в одном файле. Также он предоставляет файлы перевода для автоматической перекомпиляции при каждом изменении ваших сообщений.

person Valery Vargin    schedule 19.02.2019