Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Commit

Permalink
Convert i18n-scanner command into a webpack plugin - Closes #831
Browse files Browse the repository at this point in the history
  • Loading branch information
slaweet committed Nov 5, 2017
1 parent 84f6864 commit abea5a2
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 26 deletions.
9 changes: 9 additions & 0 deletions config/webpack.config.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { resolve } = require('path');
const webpack = require('webpack');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const I18nScannerPlugin = require('../src/i18n-scanner');
/* eslint-enable import/no-extraneous-dependencies */

const entries = {
Expand Down Expand Up @@ -37,5 +38,13 @@ module.exports = {
filename: 'styles.css',
allChunks: true,
}),
new I18nScannerPlugin({
translationFunctionNames: ['i18next.t', 'props.t', 'this.props.t', 't'],
outputFilePath: './i18n/locales/en/common.json',
files: [
'./src/**/*.js',
'./app/src/**/*.js',
],
}),
],
};
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
"pack": "npm install && npm run build && npm run clean-dist && npm run dist",
"pack:win": "cmd /c npm install && npm run clean-build && npm run copy-files && npm run build-prod && npm run build-electron && npm run clean-dist && npm run dist:win",
"storybook": "start-storybook -p 6006 -s ./src/",
"i18n-scanner": "node ./src/i18n-scanner.js",
"build-storybook": "build-storybook"
},
"author": "Lisk Foundation <admin@lisk.io>, lightcurve GmbH <admin@lightcurve.io>",
Expand Down
73 changes: 48 additions & 25 deletions src/i18n-scanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,61 @@ const fs = require('fs');
const glob = require('glob');
const Parser = require('i18next-scanner').Parser;

const translationFunctionNames = ['i18next.t', 'props.t', 'this.props.t', 't'];
const outputFilePath = './src/locales/en/common.json';

const translationsSource = JSON.parse(fs.readFileSync(outputFilePath, 'utf8'));

const parser = new Parser({
keySeparator: '>',
nsSeparator: '|',
});


const customHandler = function (key, options) {
const value = translationsSource[key] || key;
if (options.context) {
key += `_${options.context}`;
function i18nScanner(params) {
const sourceJSON = fs.readFileSync(params.outputFilePath, 'utf8');
let translationsSource;
try {
translationsSource = JSON.parse(sourceJSON);
} catch (e) {
process.stderr.write(`i18nScanner: ${e}\n`);
return;
}
parser.set(key, value);
if (options.count !== undefined) {
key = `${key}_plural`;
parser.set(key, translationsSource[key] || '');

const customHandler = function (key, options) {
const value = translationsSource[key] || key;
if (options.context) {
key += `_${options.context}`;
}
parser.set(key, value);
if (options.count !== undefined) {
key = `${key}_plural`;
parser.set(key, translationsSource[key] || '');
}
};

params.files.map(filePattern => glob.sync(filePattern, {}))
.reduce(((accumulator, files) => [...accumulator, ...files]), [])
.forEach((file) => {
const content = fs.readFileSync(file, 'utf-8');
parser.parseFuncFromString(content, { list: params.translationFunctionNames }, customHandler);
});

const translations = parser.get({ sort: true }).en.translation;
const count = Object.keys(translations).length;
const outputJSON = `${JSON.stringify(translations, null, 2)}\n`;
if (outputJSON !== sourceJSON) {
fs.writeFileSync(params.outputFilePath, outputJSON);
process.stdout.write(`i18nScanner: ${count} translation keys parsed and written to '${params.outputFilePath}'\n`);
}
};
}

const files = glob.sync('./src/**/*.js', {});
const electronFiles = glob.sync('./app/src/**/*.js', {});
[...files, ...electronFiles].forEach((file) => {
const content = fs.readFileSync(file, 'utf-8');
parser.parseFuncFromString(content, { list: translationFunctionNames }, customHandler);
});
class HelloWorldPlugin {
constructor(options) {
this.options = options;
}

apply(compiler) {
compiler.plugin('emit', (compilation, callback) => {
i18nScanner(this.options);
callback();
});
}
}

const translations = parser.get({ sort: true }).en.translation;
const count = Object.keys(translations).length;
const outputJSON = JSON.stringify(translations, null, 2);
fs.writeFileSync(outputFilePath, `${outputJSON}\n`);
process.stdout.write(`${count} translation keys parsed and written to '${outputFilePath}'`);
module.exports = HelloWorldPlugin;

0 comments on commit abea5a2

Please sign in to comment.