npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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

Readme

babel-plugin-extract-text

Babel plugin to extract strings from React components and gettext-like functions into a gettext PO file.

npm version CircleCI codecov David

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)} />
  • 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 (default false)
  • baseReferenceDir: Directory that should be used as a staring point for reference paths
  • charset: Character set for the PO (default UTF-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

  1. 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.

  1. 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.

  1. 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.