diff options
author | Nolan Lawson <nolan@nolanlawson.com> | 2017-05-22 06:06:06 -0700 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2017-05-22 15:06:06 +0200 |
commit | 9d04de1c8d3efb745cfcae3519cee016751b86ec (patch) | |
tree | 8242677e98f04c66acf6c0531d0741a238b3c360 /config/webpack | |
parent | 73e4468ff31337d1a0afdc70e1717cb5cfae2e82 (diff) |
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
Diffstat (limited to 'config/webpack')
-rw-r--r-- | config/webpack/generateLocalePacks.js | 52 | ||||
-rw-r--r-- | config/webpack/shared.js | 19 |
2 files changed, 68 insertions, 3 deletions
diff --git a/config/webpack/generateLocalePacks.js b/config/webpack/generateLocalePacks.js new file mode 100644 index 000000000..10a66e994 --- /dev/null +++ b/config/webpack/generateLocalePacks.js @@ -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; + + diff --git a/config/webpack/shared.js b/config/webpack/shared.js index 4986ea24d..1d75e2af2 100644 --- a/config/webpack/shared.js +++ b/config/webpack/shared.js @@ -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; + }, }), ], |