Skip to content

Commit

Permalink
Use single webpack build + embed only used locales in the HTML file
Browse files Browse the repository at this point in the history
  • Loading branch information
fbarl committed Apr 9, 2020
1 parent 523138d commit fc52be9
Show file tree
Hide file tree
Showing 9 changed files with 31 additions and 67 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -527,5 +527,3 @@ It should appear on the map as you refresh your local browser.
- `ERROR: for X Cannot create container for service X: Invalid bind mount spec "<path>": Invalid volume specification: '<volume spec>'`. If you get this error after running `docker-compose up` on Windows, you should tell `docker-compose` to properly understand Windows paths by setting the environment variable `COMPOSE_CONVERT_WINDOWS_PATHS` to `0` by running `setx COMPOSE_CONVERT_WINDOWS_PATHS 0`. You will also need a recent version of `docker-compose`. We have successfully seen this fix work with [v1.13.0-rc4](https://github.com/docker/toolbox/releases/tag/v1.13.0-rc4). More info here: https://github.com/docker/compose/issues/4274.

- No website found at `http://localhost:8000`: This can happen if you're running Docker in a virtual machine. Find out docker's IP using `docker-machine ip default`, and replace `localhost` by your Docker IP when connecting.

- When running `docker-compose up` you get the error: `Cannot read property 'BUNDLE_HASH' of undefined`. This can occur if your OS's default language is not english - since we by default only compile the english site. You can fix this by going into `web/package.json` and changing this line : `"watch-en": "webpack --watch --progress --mode development --config-name en"` to use the abbreviation for your system's language. ie, if your systems language is italian, you should change it to `"watch-en": "webpack --watch --progress --mode development --config-name it"`.
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ services:
- './web/topogen.sh:/home/web/topogen.sh'
- './web/views:/home/web/views'
- './web/webpack.config.js:/home/web/webpack.config.js'
web-watch-en:
web-watch:
build:
context: .
dockerfile: web/Dockerfile
Expand All @@ -43,7 +43,7 @@ services:
- eu.gcr.io/tmrow-152415/electricitymap_web:staging
- eu.gcr.io/tmrow-152415/electricitymap_web:latest
image: eu.gcr.io/tmrow-152415/electricitymap_web:latest
command: npm run watch-en
command: npm run watch
environment:
- NODE_ENV=development
volumes:
Expand Down
25 changes: 9 additions & 16 deletions mobileapp/generate-index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,6 @@ function getHash(key, ext, obj) {
}
return filename.replace('.' + ext, '').replace(key + '.', '');
}
const srcHashes = Object.fromEntries(locales.map((k) => {
const obj = JSON.parse(fs.readFileSync(`${STATIC_PATH}/dist/manifest_${k}.json`));
const BUNDLE_HASH = getHash('bundle', 'js', obj);
const STYLES_HASH = getHash('styles', 'css', obj);
const VENDOR_HASH = getHash('vendor', 'js', obj);
const VENDOR_STYLES_HASH = getHash('vendor', 'css', obj);
return [k, {
BUNDLE_HASH, STYLES_HASH, VENDOR_HASH, VENDOR_STYLES_HASH,
}];
}));

// * i18n
i18n.configure({
Expand All @@ -70,18 +60,21 @@ i18n.configure({
updateFiles: false // whether to write new locale information to disk - defaults to true
});

const template = ejs.compile(fs.readFileSync('../web/views/pages/index.ejs', 'utf8'));
const manifest = JSON.parse(fs.readFileSync(`${STATIC_PATH}/dist/manifest.json`));

locales.forEach(function(locale) {
i18n.setLocale(locale);
var template = ejs.compile(fs.readFileSync('../web/views/pages/index.ejs', 'utf8'));
var html = template({
const html = template({
alternateUrls: [],
bundleHash: srcHashes[locale].BUNDLE_HASH,
vendorHash: srcHashes[locale].VENDOR_HASH,
stylesHash: srcHashes[locale].STYLES_HASH,
vendorStylesHash: srcHashes[locale].VENDOR_STYLES_HASH,
bundleHash: getHash('bundle', 'js', manifest),
vendorHash: getHash('vendor', 'js', manifest),
stylesHash: getHash('styles', 'css', manifest),
vendorStylesHash: getHash('vendor', 'css', manifest),
isCordova: true,
locale: locale,
FBLocale: localeToFacebookLocale[locale],
locales: { en: localeConfigs['en'], [locale]: localeConfigs[locale] },
supportedLocales: locales,
supportedFBLocales: supportedFacebookLocales,
'__': function() {
Expand Down
2 changes: 1 addition & 1 deletion mobileapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@
"devDependencies": {
"app-icon": "^0.13.1"
}
}
}
3 changes: 1 addition & 2 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,11 @@
},
"scripts": {
"build-debug": "webpack --bail --progress --mode development",
"build-release": "export NODE_ENV=production && cat locales-config.json| jq '.languageNames | keys[]' | xargs -L1 -I {} node_modules/.bin/webpack --mode production --bail --config-name {}",
"build-release": "export NODE_ENV=production && webpack --bail --mode production",
"clean": "mkdir -p public/dist && rm public/dist/bundle.*.js",
"lint": "eslint --quiet src",
"server-dev": "nodemon server.js",
"watch": "webpack --watch --progress --mode development",
"watch-en": "webpack --watch --progress --mode development --config-name en",
"watch-poll": "webpack --watch --watch-poll --progress --mode development"
},
"browserslist": [
Expand Down
26 changes: 7 additions & 19 deletions web/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,8 @@ function getHash(key, ext, obj) {
}
return filename.replace('.' + ext, '').replace(key + '.', '');
}
const srcHashes = Object.fromEntries(locales.map((k) => {
try {
const obj = JSON.parse(fs.readFileSync(`${STATIC_PATH}/dist/manifest_${k}.json`));
const BUNDLE_HASH = getHash('bundle', 'js', obj);
const STYLES_HASH = getHash('styles', 'css', obj);
const VENDOR_HASH = getHash('vendor', 'js', obj);
const VENDOR_STYLES_HASH = getHash('vendor', 'css', obj);
return [k, {
BUNDLE_HASH, STYLES_HASH, VENDOR_HASH, VENDOR_STYLES_HASH,
}];
} catch (err) {
console.warn(`Warning: couldn't load manifest for locale ${k}: ${err}`);
return null; // Ignore
}
}).filter(d => d));

const manifest = JSON.parse(fs.readFileSync(`${STATIC_PATH}/dist/manifest.json`));

// * Error handling
function handleError(err) {
Expand Down Expand Up @@ -189,12 +176,13 @@ app.get('/', (req, res) => {
}
}
}),
bundleHash: srcHashes[locale].BUNDLE_HASH,
vendorHash: srcHashes[locale].VENDOR_HASH,
stylesHash: srcHashes[locale].STYLES_HASH,
vendorStylesHash: srcHashes[locale].VENDOR_STYLES_HASH,
bundleHash: getHash('bundle', 'js', manifest),
vendorHash: getHash('vendor', 'js', manifest),
stylesHash: getHash('styles', 'css', manifest),
vendorStylesHash: getHash('vendor', 'css', manifest),
fullUrl,
locale,
locales: { en: localeConfigs['en'], [locale]: localeConfigs[locale] },
supportedLocales: locales,
FBLocale: localeToFacebookLocale[locale],
supportedFBLocales: supportedFacebookLocales,
Expand Down
11 changes: 2 additions & 9 deletions web/src/helpers/translation.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
/* eslint-disable import/no-dynamic-require */
/* eslint-disable global-require */
/* eslint-disable prefer-rest-params */
/* eslint-disable prefer-spread */
// TODO: re-enable rules

// Import locales required
const locales = {
en: require('../../locales/en.json'),
[locale]: require(`../../locales/${locale}.json`),
};
const { vsprintf } = require('sprintf-js');
import { vsprintf } from 'sprintf-js';

function translateWithLocale(locale, keyStr) {
const keys = keyStr.split('.');
let result = locales[locale];
let result = window.locales[locale];
for (let i = 0; i < keys.length; i += 1) {
if (result == null) { break; }
result = result[keys[i]];
Expand Down
1 change: 1 addition & 0 deletions web/views/pages/index.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
var bundleHash = '<%= bundleHash %>';
var locale = '<%= locale %>';
var FBLocale = '<%= FBLocale %>';
var locales = <%- JSON.stringify(locales) %>;
var isCordova = <%= (typeof isCordova !== 'undefined' && isCordova) %>;
</script>

Expand Down
24 changes: 8 additions & 16 deletions web/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

const isProduction = process.env.NODE_ENV === 'production';
const { languageNames } = require('./locales-config.json');

const { version } = require('./package.json');

/*
Note exporting a config per language makes the build slower.
Sequential builds are faster (using jq and `--config-name`)
*/
module.exports = Object.keys(languageNames).map(locale => ({
name: locale,
module.exports = {
devtool: isProduction ? 'sourcemap' : 'eval',
entry: { bundle: ['@babel/polyfill', './src/main.js'], styles: './src/scss/styles.scss' },
entry: {
bundle: ['@babel/polyfill', './src/main.js'],
styles: './src/scss/styles.scss',
},
module: {
noParse: /(mapbox-gl)\.js$/,
rules: [
Expand All @@ -44,9 +41,6 @@ module.exports = Object.keys(languageNames).map(locale => ({
],
},
plugins: [
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, new RegExp(`/${locale}/`)),
// Only include current locale + en
new webpack.ContextReplacementPlugin(/locales/, new RegExp(`/${locale}|en/`)),
new OptimizeCssAssetsPlugin(),
new MiniCssExtractPlugin({
filename: '[name].' + (isProduction ? '[chunkhash]' : 'dev') + '.css',
Expand All @@ -56,7 +50,7 @@ module.exports = Object.keys(languageNames).map(locale => ({
function () {
this.plugin('done', (stats) => {
fs.writeFileSync(
`${__dirname}/public/dist/manifest_${locale}.json`,
`${__dirname}/public/dist/manifest.json`,
JSON.stringify(stats.toJson())
);
});
Expand All @@ -82,9 +76,7 @@ module.exports = Object.keys(languageNames).map(locale => ({
},
output: {
// filename affects styles.js and bundle.js
filename: chunkData => (['styles'].includes(chunkData.chunk.name)
? `[name].${isProduction ? '[chunkhash]' : 'dev'}.js`
: `[name].${isProduction ? '[chunkhash]' : 'dev'}.${locale}.js`),
filename: `[name].${isProduction ? '[chunkhash]' : 'dev'}.js`,
// chunkFilename affects `vendor.js`
chunkFilename: `[name].${isProduction ? '[chunkhash]' : 'dev'}.js`,
path: `${__dirname}/public/dist`,
Expand All @@ -94,4 +86,4 @@ module.exports = Object.keys(languageNames).map(locale => ({
node: {
fs: 'empty',
},
}));
};

0 comments on commit fc52be9

Please sign in to comment.