reimplemented l10n using dynamic import() (#1012)
this should greatly reduce the complexity of the l10n code and build pipeline and eliminate the most common error seen in sentry logs (no translate function)
This commit is contained in:
parent
5afa4e5c9b
commit
1e62aa976d
28 changed files with 145 additions and 280 deletions
|
@ -15,16 +15,6 @@ function chunkFileNames(compilation) {
|
|||
}
|
||||
class AndroidIndexPlugin {
|
||||
apply(compiler) {
|
||||
const assets = {};
|
||||
compiler.hooks.compilation.tap(NAME, compilation => {
|
||||
compilation.hooks.moduleAsset.tap(NAME, (mod, file) => {
|
||||
if (mod.userRequest) {
|
||||
assets[
|
||||
path.join(path.dirname(file), path.basename(mod.userRequest))
|
||||
] = file;
|
||||
}
|
||||
});
|
||||
});
|
||||
compiler.hooks.emit.tap(NAME, compilation => {
|
||||
const files = chunkFileNames(compilation);
|
||||
const page = html`
|
||||
|
@ -36,9 +26,8 @@ class AndroidIndexPlugin {
|
|||
name="viewport"
|
||||
content="width=device-width, initial-scale=1"
|
||||
/>
|
||||
<base href="file:///android_asset/" />
|
||||
<link href="${files['app.css']}" rel="stylesheet" />
|
||||
<script src="${files['vendor.js']}"></script>
|
||||
<script src="${assets['public/locales/en-US/send.ftl']}"></script>
|
||||
<script src="${files['android.js']}"></script>
|
||||
</head>
|
||||
<body></body>
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
const { FluentResource } = require('fluent/compat');
|
||||
const fs = require('fs');
|
||||
|
||||
function toJSON(resource) {
|
||||
return JSON.stringify(Array.from(resource));
|
||||
}
|
||||
|
||||
module.exports = function(source) {
|
||||
const localeExp = /([^/]+)\/[^/]+\.ftl$/;
|
||||
const result = localeExp.exec(this.resourcePath);
|
||||
const locale = result && result[1];
|
||||
if (!locale) {
|
||||
throw new Error(`couldn't find locale in: ${this.resourcePath}`);
|
||||
}
|
||||
|
||||
// Parse the current language's translation file.
|
||||
const locResource = FluentResource.fromString(source);
|
||||
let enResource;
|
||||
|
||||
// If the current language is not en-US, also parse en-US to provide a
|
||||
// fallback for missing translations.
|
||||
if (locale !== 'en-US') {
|
||||
const en_ftl = fs.readFileSync(
|
||||
require.resolve('../public/locales/en-US/send.ftl'),
|
||||
'utf8'
|
||||
);
|
||||
enResource = FluentResource.fromString(en_ftl);
|
||||
}
|
||||
|
||||
return `
|
||||
module.exports = \`
|
||||
if (typeof window === 'undefined') {
|
||||
var fluent = require('fluent');
|
||||
}
|
||||
(function () {
|
||||
let bundles = [
|
||||
['${locale}', ${toJSON(locResource)}],
|
||||
${enResource ? `['en-US', ${toJSON(enResource)}]` : ''}
|
||||
].map(([locale, entries]) => {
|
||||
let bundle = new fluent.FluentBundle(locale, {useIsolating: false});
|
||||
bundle.addResource(new fluent.FluentResource(entries));
|
||||
return bundle;
|
||||
});
|
||||
|
||||
function translate(id, data) {
|
||||
for (let bundle of bundles) {
|
||||
if (bundle.hasMessage(id)) {
|
||||
let message = bundle.getMessage(id);
|
||||
return bundle.format(message, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
module.exports = translate;
|
||||
}
|
||||
else {
|
||||
window.translate = translate;
|
||||
}
|
||||
})();
|
||||
\``;
|
||||
};
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
This code is included by both the server and frontend via
|
||||
common/locales.js
|
||||
|
||||
When included from the server the export will be the function.
|
||||
|
||||
When included from the frontend (via webpack) the export will
|
||||
be an object mapping ftl files to js files. Example:
|
||||
"public/locales/en-US/send.ftl":"public/locales/en-US/send.6b4f8354.js"
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function kv(d) {
|
||||
return `"${d}": require('../public/locales/${d}/send.ftl')`;
|
||||
}
|
||||
|
||||
module.exports = function() {
|
||||
const dirs = fs.readdirSync(path.join(__dirname, '..', 'public', 'locales'));
|
||||
const code = `
|
||||
module.exports = {
|
||||
translate: function (id, data) { return window.translate(id, data) },
|
||||
${dirs.map(kv).join(',\n')}
|
||||
};`;
|
||||
return {
|
||||
code,
|
||||
dependencies: dirs.map(d =>
|
||||
require.resolve(`../public/locales/${d}/send.ftl`)
|
||||
),
|
||||
cacheable: true
|
||||
};
|
||||
};
|
|
@ -1,17 +1,9 @@
|
|||
# Custom Loaders
|
||||
|
||||
## Fluent Loader
|
||||
|
||||
The fluent loader "compiles" `.ftl` files into `.js` files directly usable by both the frontend and server for localization.
|
||||
|
||||
## Generate Asset Map
|
||||
|
||||
This loader enumerates all the files in `assets/` so that `common/assets.js` can provide mappings from the source filename to the hashed filename used on the site.
|
||||
|
||||
## Generate L10N Map
|
||||
|
||||
This loader enumerates all the ftl files in `public/locales` so that the fluent loader can create it's js files.
|
||||
|
||||
## Version Plugin
|
||||
|
||||
Creates a `version.json` file that gets exposed by the `/__version__` route from the `package.json` file and current git commit hash.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue