Skip to content

Instantly share code, notes, and snippets.

@marr
Last active August 12, 2016 16:49
react-intl-webpack-plugin
import * as fs from 'fs'
import path from 'path'
import { sync as globSync } from 'glob'
import { sync as mkdirpSync } from 'mkdirp'
const MESSAGES_PATTERN = './dist/messages/**/*.json'
const LANG_DIR = './dist/lang/'
export default function() {
// 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 }) => {
if (collection.hasOwnProperty(id)) {
throw new Error(`Duplicate message id: ${id}`)
}
collection[id] = defaultMessage
})
return collection
}, {})
mkdirpSync(LANG_DIR)
// Write out default locale
// TODO: Write out other locales
fs.writeFileSync(LANG_DIR + 'en-US.json', JSON.stringify(defaultMessages, null, 2))
}
import extractStrings from './extract-strings'
import translator from './translator'
function ReactIntlWebpackPlugin() { }
// inspired by https://github.com/yahoo/react-intl/tree/master/examples/translations/scripts/translate.js
ReactIntlWebpackPlugin.prototype.apply = function(compiler) {
compiler.plugin('compilation', function(compilation) {
compilation.plugin('html-webpack-plugin-before-html-generation', function(htmlPluginData, callback) {
if (htmlPluginData.plugin.options.app) {
extractStrings()
htmlPluginData.plugin.options.app = JSON.stringify(translator())
}
callback()
})
})
}
export default ReactIntlWebpackPlugin
import path from 'path'
import { readFileSync } from 'fs'
import { sync as globSync } from 'glob'
export default function translator(locale = 'en-US') {
// Build translations from extracted strings
const translations = globSync('./dist/lang/*.json')
.map((filename) => [
path.basename(filename, '.json'),
readFileSync(filename, 'utf8'),
])
.map(([locale, file]) => [locale, JSON.parse(file)])
.reduce((collection, [locale, messages]) => {
collection[locale] = messages
return collection
}, {})
return {
locale,
messages: translations[locale]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment