babel-plugin-extract-text
v2.0.0
Published
Babel plugin to extract strings from React components and gettext-like functions into a gettext PO file
Downloads
1,055
Maintainers
Readme
babel-plugin-extract-text
Babel plugin to extract strings from React components and gettext-like functions into a gettext PO file.
Features
- Extraction from React components
- Verbose style:
<LocalizedString id="Nice cat!" idPlural="Nice cats!" count={numCats} />
- Shortform style:
<LocalizedString i18n={_n('Nice cat!', 'Nice cats!', numCats)} />
- Verbose style:
- Extraction from gettext-like functions
_('Hello World')
- Customizable extraction (e.g. component name, function names and function argument positions)
- Supports translator comments and context
- Validation (e.g. props missing on component, non-string literals are used for call expression arguments)
Setup
Begin with installing this plugin and the JSX plugin for Babel
yarn add --dev babel-plugin-extract-text @babel/syntax-jsx
In a babel configuration, add both plugins and set the options
{ plugins: ['@babel/syntax-jsx', ['extract-text', { ... options ... }]] }
Options
This plugin allows a number of configurations to be passed:
outputFile
: Output PO file name (default is the${currentFileProcessed}.po
)outputDir
: Output directory (default is dir of the current file being processed)includeReference
: Whether to include a file reference for PO entries (defaultfalse
)baseReferenceDir
: Directory that should be used as a staring point for reference pathscharset
: Character set for the PO (defaultUTF-8
)headers
: Object indicating all PO headers to include. See the default headers here.component
/function
: Objects customizing the extraction for component/function respectively. This includes the React component name to look for, the function names, and so on. See the default configuration here.
Example
Plugin Configuration
const babel = require('babel-core')
babel.transformFile('someCode.js', {
plugins: [
'@babel/syntax-jsx',
['extract-text', {
includeReference: true,
headers: {
'po-revision-date': new Date().toISOString(),
},
component: {
name: 'Message',
singular: 'id',
plural: 'idPlural',
context: 'context',
comment: 'comment',
shortform: 'i18n',
},
}],
],
}, (error) => error ? console.log(error) : console.log('Done!'))
Input (someCode.js
)
// Verbose style, specifying gettext args via props
<Message
id="You have a cat."
idPlural="You have {cats} cats!"
comment="User profile description for a public profile"
count={numCats}
cats={numCatsFormatted} />
// Shortform style, using gettext function directly
<Message i18n={_('Hello World')} />
_c('Flag', 'Physical Object')
Output (someCode.js.po
)
msgid ""
msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"Language: en_US\n"
"PO-Revision-Date: 2017-02-08T05:27:35.094Z\n"
#: someCode.js
#. User profile description for a public profile
msgid "You have a cat."
msgid_plural "You have {cats} cats!"
msgstr[0] ""
msgstr[1] ""
#: someCode.js
msgctxt "Physical Object"
msgid "Flag"
msgstr ""
#: someCode.js
msgid "Hello World"
msgstr ""
Next Steps
You can use my other library react-translations, which plays nicely with this babel plugin. Otherwise you'll need to build out these components and hook them up to a basic gettext client such as Jed.
Motivation
- Why not use ICU MessageFormat?
ICU patterns strings, while pretty powerful, can become clunkly very fast. Gettext style strings should be enough to cover the typical use cases and are easy to use and understand. More importantly, ICU strings are not always supported by translators and translation providers, whereas the PO format is a de facto standard.
- Why not use xgettext to extract?
xgettext is a difficult dependency to install and manage since it's not native to the JS ecosystem. Also, xgettext will only support extraction from call expressions. Regardless, the tool definitely does not support JSX/ES6, so you'll be running your code through Babel anyway.
- Why not use a simple JSON format for strings (or some format X)?
Many extraction tools invent their own format, or use a basic JSON structure, which either ends up being too simple (e.g. not able to support pluralization) and/or not translator friendly (translators are used to working with certain formats). Gettext/PO is a proven method for translation that satisfies everyone: translators, developers, product, and users.
Acknowledgements
Thanks to the folks over at Sentry for their blog post, and their extractor tool, both of which served as an inspiration for me to utilize Babel to extend the extraction process to React.