Build translations with webpack
Convert the `po2json` script into a webpack plugin, and integrate the (now trivial) po.empty.js template. This is the last step for building the entire dist/ directory with `npm run build` (i.e. a tool that web developers are familiar with), and not having a split webpack+make toolchain any more.
This commit is contained in:
parent
07017f79d8
commit
7f6ef51c12
5 changed files with 81 additions and 137 deletions
7
Makefile
7
Makefile
|
|
@ -45,11 +45,6 @@ update-po: po/$(PACKAGE_NAME).pot
|
||||||
msgmerge --output-file=po/$$lang.po po/$$lang.po $<; \
|
msgmerge --output-file=po/$$lang.po po/$$lang.po $<; \
|
||||||
done
|
done
|
||||||
|
|
||||||
dist/po.%.js: po/%.po $(NODE_MODULES_TEST)
|
|
||||||
mkdir -p $(dir $@)
|
|
||||||
po/po2json -m po/po.empty.js -o $@.js.tmp $<
|
|
||||||
mv $@.js.tmp $@
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build/Install/dist
|
# Build/Install/dist
|
||||||
#
|
#
|
||||||
|
|
@ -57,7 +52,7 @@ dist/po.%.js: po/%.po $(NODE_MODULES_TEST)
|
||||||
%.spec: %.spec.in
|
%.spec: %.spec.in
|
||||||
sed -e 's/%{VERSION}/$(VERSION)/g' $< > $@
|
sed -e 's/%{VERSION}/$(VERSION)/g' $< > $@
|
||||||
|
|
||||||
$(WEBPACK_TEST): $(NODE_MODULES_TEST) src/lib/patternfly/_fonts.scss $(shell find src/ -type f) package.json webpack.config.js $(patsubst %,dist/po.%.js,$(LINGUAS))
|
$(WEBPACK_TEST): $(NODE_MODULES_TEST) src/lib/patternfly/_fonts.scss $(shell find src/ -type f) package.json webpack.config.js
|
||||||
NODE_ENV=$(NODE_ENV) npm run build
|
NODE_ENV=$(NODE_ENV) npm run build
|
||||||
|
|
||||||
watch:
|
watch:
|
||||||
|
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
/* The syntax of this line is important for po2json */
|
|
||||||
cockpit.locale({"":{"language":"en"}});
|
|
||||||
127
po/po2json
127
po/po2json
|
|
@ -1,127 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
function fatal(message, code) {
|
|
||||||
console.log((filename || "html2po") + ": " + message);
|
|
||||||
process.exit(code || 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function usage() {
|
|
||||||
console.log("usage: po2json [--module=template.js] [--output=output.js] input");
|
|
||||||
process.exit(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
var fs, po2json, Jed, stdio;
|
|
||||||
|
|
||||||
try {
|
|
||||||
fs = require('fs');
|
|
||||||
po2json = require('po2json');
|
|
||||||
Jed = require('jed');
|
|
||||||
stdio = require('stdio');
|
|
||||||
} catch(ex) {
|
|
||||||
fatal(ex.message, 127); /* missing looks for this */
|
|
||||||
}
|
|
||||||
|
|
||||||
var argi = 2;
|
|
||||||
var filename = null;
|
|
||||||
|
|
||||||
var opts = stdio.getopt({
|
|
||||||
module: { key: "m", args: 1, description: "Module template to include", default: "" },
|
|
||||||
output: { key: "o", args: 1, description: "Output file", default: "" },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!opts.args || opts.args.length != 1) {
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
parse();
|
|
||||||
|
|
||||||
function prepareHeader(header) {
|
|
||||||
var body, statement, plurals = header["plural-forms"], ret = null;
|
|
||||||
if (plurals) {
|
|
||||||
try {
|
|
||||||
/* Check that the plural forms isn't being sneaky since we build a function here */
|
|
||||||
Jed.PF.parse(plurals);
|
|
||||||
} catch(ex) {
|
|
||||||
fatal("bad plural forms: " + ex.message, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A function for the front end */
|
|
||||||
statement = header["plural-forms"];
|
|
||||||
if (statement[statement.length - 1] != ';')
|
|
||||||
statement += ';';
|
|
||||||
ret = 'function(n) {\nvar nplurals, plural;\n' + statement + '\nreturn plural;\n}';
|
|
||||||
|
|
||||||
/* Added back in later */
|
|
||||||
delete header["plural-forms"];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We don't need to be transferring this */
|
|
||||||
delete header["project-id-version"];
|
|
||||||
delete header["report-msgid-bugs-to"];
|
|
||||||
delete header["pot-creation-date"];
|
|
||||||
delete header["po-revision-date"];
|
|
||||||
delete header["last-translator"];
|
|
||||||
delete header["language-team"];
|
|
||||||
delete header["mime-version"];
|
|
||||||
delete header["content-type"];
|
|
||||||
delete header["content-transfer-encoding"];
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse and process the po data */
|
|
||||||
function parse() {
|
|
||||||
filename = opts.args[0];
|
|
||||||
po2json.parseFile(opts.args[0], { "fuzzy": false }, function(err, jsonData) {
|
|
||||||
var plurals, pos;
|
|
||||||
|
|
||||||
if (err)
|
|
||||||
fatal(err.message);
|
|
||||||
|
|
||||||
var header = jsonData[""];
|
|
||||||
if (header)
|
|
||||||
plurals = prepareHeader(header);
|
|
||||||
|
|
||||||
var data = JSON.stringify(jsonData, null, 1);
|
|
||||||
|
|
||||||
/* We know the brace in is the location to insert our function */
|
|
||||||
if (plurals) {
|
|
||||||
pos = data.indexOf('{', 1);
|
|
||||||
data = data.substr(0, pos + 1) + "'plural-forms':" + String(plurals) + "," + data.substr(pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data == JSON.stringify({}))
|
|
||||||
finish("");
|
|
||||||
else
|
|
||||||
wrap(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wrap the data if desired */
|
|
||||||
function wrap(data) {
|
|
||||||
if (opts.module) {
|
|
||||||
filename = opts.module;
|
|
||||||
fs.readFile(opts.module, { encoding: "utf-8" }, function(err, template) {
|
|
||||||
if (err)
|
|
||||||
fatal(err.message);
|
|
||||||
data = template.replace('{"":{"language":"en"}}', data);
|
|
||||||
finish(data);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
finish(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write it out */
|
|
||||||
function finish(data) {
|
|
||||||
if (opts.output) {
|
|
||||||
fs.writeFile(opts.output, data, function(err) {
|
|
||||||
if (err)
|
|
||||||
fatal(err.message);
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
process.stdout.write(data);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
74
src/lib/cockpit-po-plugin.js
Normal file
74
src/lib/cockpit-po-plugin.js
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
const path = require("path");
|
||||||
|
const glob = require("glob");
|
||||||
|
const po2json = require('po2json');
|
||||||
|
const Jed = require('jed');
|
||||||
|
|
||||||
|
module.exports = class {
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.emit.tapPromise(
|
||||||
|
'CockpitPoPlugin',
|
||||||
|
compilation => Promise.all(glob.sync('po/*.po').map(f => this.buildFile(f, compilation)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareHeader(header) {
|
||||||
|
if (!header)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var body, statement, ret = null;
|
||||||
|
const plurals = header["plural-forms"];
|
||||||
|
|
||||||
|
if (plurals) {
|
||||||
|
try {
|
||||||
|
/* Check that the plural forms isn't being sneaky since we build a function here */
|
||||||
|
Jed.PF.parse(plurals);
|
||||||
|
} catch(ex) {
|
||||||
|
fatal("bad plural forms: " + ex.message, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A function for the front end */
|
||||||
|
statement = header["plural-forms"];
|
||||||
|
if (statement[statement.length - 1] != ';')
|
||||||
|
statement += ';';
|
||||||
|
ret = 'function(n) {\nvar nplurals, plural;\n' + statement + '\nreturn plural;\n}';
|
||||||
|
|
||||||
|
/* Added back in later */
|
||||||
|
delete header["plural-forms"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We don't need to be transferring this */
|
||||||
|
delete header["project-id-version"];
|
||||||
|
delete header["report-msgid-bugs-to"];
|
||||||
|
delete header["pot-creation-date"];
|
||||||
|
delete header["po-revision-date"];
|
||||||
|
delete header["last-translator"];
|
||||||
|
delete header["language-team"];
|
||||||
|
delete header["mime-version"];
|
||||||
|
delete header["content-type"];
|
||||||
|
delete header["content-transfer-encoding"];
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildFile(po_file, compilation) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const jsonData = po2json.parseFileSync(po_file);
|
||||||
|
const plurals = this.prepareHeader(jsonData[""]);
|
||||||
|
|
||||||
|
let output = JSON.stringify(jsonData, null, 1);
|
||||||
|
|
||||||
|
// We know the brace in is the location to insert our function
|
||||||
|
if (plurals) {
|
||||||
|
pos = output.indexOf('{', 1);
|
||||||
|
output = output.substr(0, pos + 1) + "'plural-forms':" + String(plurals) + "," + output.substr(pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrap JSON output into cockpit.locale() call
|
||||||
|
output = 'cockpit.locale(' + output + ');\n';
|
||||||
|
|
||||||
|
const lang = path.basename(po_file).slice(0, -3)
|
||||||
|
compilation.assets['po.' + lang + '.js'] = { source: () => output, size: () => output.length };
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const childProcess = require('child_process');
|
const childProcess = require('child_process');
|
||||||
|
|
||||||
const copy = require("copy-webpack-plugin");
|
const copy = require("copy-webpack-plugin");
|
||||||
const extract = require("mini-css-extract-plugin");
|
const extract = require("mini-css-extract-plugin");
|
||||||
const TerserJSPlugin = require('terser-webpack-plugin');
|
const TerserJSPlugin = require('terser-webpack-plugin');
|
||||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||||
const webpack = require("webpack");
|
|
||||||
const CompressionPlugin = require("compression-webpack-plugin");
|
const CompressionPlugin = require("compression-webpack-plugin");
|
||||||
|
const CockpitPoPlugin = require("./src/lib/cockpit-po-plugin");
|
||||||
|
|
||||||
|
const webpack = require("webpack");
|
||||||
|
|
||||||
const nodedir = path.resolve((process.env.SRCDIR || __dirname), "node_modules");
|
const nodedir = path.resolve((process.env.SRCDIR || __dirname), "node_modules");
|
||||||
|
|
||||||
|
|
@ -20,7 +23,8 @@ const copy_files = [
|
||||||
|
|
||||||
const plugins = [
|
const plugins = [
|
||||||
new copy({ patterns: copy_files }),
|
new copy({ patterns: copy_files }),
|
||||||
new extract({filename: "[name].css"})
|
new extract({filename: "[name].css"}),
|
||||||
|
new CockpitPoPlugin(),
|
||||||
];
|
];
|
||||||
|
|
||||||
/* Only minimize when in production mode */
|
/* Only minimize when in production mode */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue