0
0
Fork 0

Only load Intl data for current language (#3130)

* Only load Intl data for current language

* Extract common chunk only from application.js and public.js

* Generate locale packs, avoid caching on window object
This commit is contained in:
Nolan Lawson 2017-05-22 06:06:06 -07:00 committed by Eugen Rochko
parent 73e4468ff3
commit 9d04de1c8d
7 changed files with 90 additions and 139 deletions

View file

@ -0,0 +1,52 @@
// To avoid adding a lot of boilerplate, locale packs are
// automatically generated here. These are written into the tmp/
// directory and then used to generate locale_en.js, locale_fr.js, etc.
const fs = require('fs');
const path = require('path');
const rimraf = require('rimraf');
const mkdirp = require('mkdirp');
const localesJsonPath = path.join(__dirname, '../../app/javascript/mastodon/locales');
const locales = fs.readdirSync(localesJsonPath).filter(filename => {
return /\.json$/.test(filename) &&
!/defaultMessages/.test(filename) &&
!/whitelist/.test(filename);
}).map(filename => filename.replace(/\.json$/, ''));
const outPath = path.join(__dirname, '../../tmp/packs');
rimraf.sync(outPath);
mkdirp.sync(outPath);
const outPaths = [];
locales.forEach(locale => {
const localePath = path.join(outPath, `locale_${locale}.js`);
const baseLocale = locale.split('-')[0]; // e.g. 'zh-TW' -> 'zh'
const localeDataPath = [
// first try react-intl
`../../node_modules/react-intl/locale-data/${baseLocale}.js`,
// then check locales/locale-data
`../../app/javascript/mastodon/locales/locale-data/${baseLocale}.js`,
// fall back to English (this is what react-intl does anyway)
`../../node_modules/react-intl/locale-data/en.js`,
].filter(filename => fs.existsSync(path.join(outPath, filename)))
.map(filename => filename.replace(/..\/..\/node_modules\//, ''))[0];
const localeContent = `//
// locale_${locale}.js
// automatically generated by generateLocalePacks.js
//
import messages from '../../app/javascript/mastodon/locales/${locale}.json';
import localeData from ${JSON.stringify(localeDataPath)};
import { setLocale } from '../../app/javascript/mastodon/locales';
setLocale({messages, localeData});
`;
fs.writeFileSync(localePath, localeContent, 'utf8');
outPaths.push(localePath);
});
module.exports = outPaths;

View file

@ -10,15 +10,20 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const extname = require('path-complete-extname');
const { env, paths, publicPath, loadersDir } = require('./configuration.js');
const localePackPaths = require('./generateLocalePacks');
const extensionGlob = `**/*{${paths.extensions.join(',')}}*`;
const packPaths = sync(join(paths.source, paths.entry, extensionGlob));
const entryPacks = [].concat(packPaths).concat(localePackPaths);
module.exports = {
entry: packPaths.reduce(
entry: entryPacks.reduce(
(map, entry) => {
const localMap = map;
const namespace = relative(join(paths.source, paths.entry), dirname(entry));
let namespace = relative(join(paths.source, paths.entry), dirname(entry));
if (namespace === '../../../tmp/packs') {
namespace = ''; // generated by generateLocalePacks.js
}
localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry);
return localMap;
}, {}
@ -41,7 +46,15 @@ module.exports = {
new ManifestPlugin({ fileName: paths.manifest, publicPath, writeToFileEmit: true }),
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: 2,
minChunks: (module, count) => {
if (module.resource && /node_modules\/react-intl/.test(module.resource)) {
// skip react-intl because it's useless to put in the common chunk,
// e.g. because "shared" modules between zh-TW and zh-CN will never
// be loaded together
return false;
}
return count >= 2;
},
}),
],