add localisation via ttag
This commit is contained in:
parent
087319be96
commit
0c5ab8bf97
13
i18n/de.po
Normal file
13
i18n/de.po
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
|
"Plural-Forms: nplurals = 2; plural = (n != 1);\n"
|
||||||
|
"Language: de\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: src/components/ForgotPasswordModal.jsx:20
|
||||||
|
#: src/components/RegisterModal.jsx:21
|
||||||
|
#: src/components/UserAreaModal.jsx:128
|
||||||
|
msgid "Consider joining us on Guilded:"
|
||||||
|
msgstr "Sprich zu uns und anderen Spielern auf guilded:"
|
13
i18n/es.po
Normal file
13
i18n/es.po
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
|
"Plural-Forms: nplurals = 2; plural = (n != 1);\n"
|
||||||
|
"Language: de\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: src/components/ForgotPasswordModal.jsx:20
|
||||||
|
#: src/components/RegisterModal.jsx:21
|
||||||
|
#: src/components/UserAreaModal.jsx:128
|
||||||
|
msgid "Consider joining us on Guilded:"
|
||||||
|
msgstr "Sprich zu uns und anderen Spielern auf guilded:"
|
919
package-lock.json
generated
919
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -77,6 +77,7 @@
|
||||||
"sweetalert2": "^10.12.1",
|
"sweetalert2": "^10.12.1",
|
||||||
"three": "^0.123.0",
|
"three": "^0.123.0",
|
||||||
"three-trackballcontrols": "^0.9.0",
|
"three-trackballcontrols": "^0.9.0",
|
||||||
|
"ttag": "^1.7.24",
|
||||||
"url-search-params-polyfill": "^8.1.0",
|
"url-search-params-polyfill": "^8.1.0",
|
||||||
"winston": "^3.3.3",
|
"winston": "^3.3.3",
|
||||||
"winston-daily-rotate-file": "^4.5.0",
|
"winston-daily-rotate-file": "^4.5.0",
|
||||||
|
@ -115,6 +116,7 @@
|
||||||
"babel-loader": "^8.2.2",
|
"babel-loader": "^8.2.2",
|
||||||
"babel-plugin-transform-react-pure-class-to-function": "^1.0.1",
|
"babel-plugin-transform-react-pure-class-to-function": "^1.0.1",
|
||||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
||||||
|
"babel-plugin-ttag": "^1.7.30",
|
||||||
"clean-css": "^4.2.3",
|
"clean-css": "^4.2.3",
|
||||||
"css-loader": "^5.0.1",
|
"css-loader": "^5.0.1",
|
||||||
"eslint": "^7.15.0",
|
"eslint": "^7.15.0",
|
||||||
|
@ -134,6 +136,7 @@
|
||||||
"react-svg-loader": "^3.0.3",
|
"react-svg-loader": "^3.0.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"style-loader": "^2.0.0",
|
"style-loader": "^2.0.0",
|
||||||
|
"ttag-cli": "^1.9.1",
|
||||||
"webpack": "^5.10.0",
|
"webpack": "^5.10.0",
|
||||||
"webpack-bundle-analyzer": "^4.2.0",
|
"webpack-bundle-analyzer": "^4.2.0",
|
||||||
"webpack-cli": "^4.2.0",
|
"webpack-cli": "^4.2.0",
|
||||||
|
|
|
@ -7,27 +7,31 @@
|
||||||
* LICENSE.txt file in the root directory of this source tree.
|
* LICENSE.txt file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
import webpack from 'webpack';
|
import webpack from 'webpack';
|
||||||
import webpackConfigWeb from '../webpack.config.web.babel';
|
import webpackConfigWeb from '../webpack.config.web.babel';
|
||||||
import webpackConfigClient from '../webpack.config.client.babel';
|
import { buildWebpackClientConfig } from '../webpack.config.client.babel';
|
||||||
|
|
||||||
const wpStats = {
|
const wpStats = {
|
||||||
colors: true,
|
colors: true,
|
||||||
reasons: false,
|
reasons: false,
|
||||||
hash: false,
|
hash: false,
|
||||||
version: false,
|
version: false,
|
||||||
timings: true,
|
timings: true,
|
||||||
chunks: true,
|
chunks: true,
|
||||||
chunkModules: false,
|
chunkModules: false,
|
||||||
cached: false,
|
cached: false,
|
||||||
cachedAssets: false,
|
cachedAssets: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates application bundles from the source files.
|
* Creates application bundles from the source files.
|
||||||
*/
|
*/
|
||||||
function bundle() {
|
async function bundle() {
|
||||||
try {
|
try {
|
||||||
/* fix image-q imports here
|
/* fix image-q imports here
|
||||||
* Pretty dirty, but we did write an issue and they might
|
* Pretty dirty, but we did write an issue and they might
|
||||||
|
@ -36,12 +40,21 @@ function bundle() {
|
||||||
console.log('Patching image-q set-immediate import');
|
console.log('Patching image-q set-immediate import');
|
||||||
const regex = /core-js\/fn\/set-immediate/g;
|
const regex = /core-js\/fn\/set-immediate/g;
|
||||||
const files = [
|
const files = [
|
||||||
'./node_modules/image-q/dist/esm/basicAPI.js',
|
path.resolve(
|
||||||
'./node_modules/image-q/dist/esm/helper.js',
|
'..', 'node_modules',
|
||||||
|
'image-q', 'dist', 'esm', 'basicAPI.js',
|
||||||
|
),
|
||||||
|
path.resolve(
|
||||||
|
'..', 'node_modules',
|
||||||
|
'image-q', 'dist', 'esm', 'helper.js',
|
||||||
|
),
|
||||||
];
|
];
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
let fileContent = fs.readFileSync(file,'utf8');
|
let fileContent = fs.readFileSync(file, 'utf8');
|
||||||
fileContent = fileContent.replace(regex, 'core-js/features/set-immediate');
|
fileContent = fileContent.replace(
|
||||||
|
regex,
|
||||||
|
'core-js/features/set-immediate',
|
||||||
|
);
|
||||||
fs.writeFileSync(file, fileContent);
|
fs.writeFileSync(file, fileContent);
|
||||||
});
|
});
|
||||||
console.log('Patching image-q done');
|
console.log('Patching image-q done');
|
||||||
|
@ -50,8 +63,24 @@ function bundle() {
|
||||||
}
|
}
|
||||||
console.log('Bundle with webpack....');
|
console.log('Bundle with webpack....');
|
||||||
|
|
||||||
|
let webpackConfig = [
|
||||||
|
webpackConfigWeb,
|
||||||
|
buildWebpackClientConfig(false, false, 'default'),
|
||||||
|
]
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add other language configs
|
||||||
|
*/
|
||||||
|
const langDir = path.resolve(__dirname, '..', 'i18n');
|
||||||
|
const langs = fs.readdirSync(langDir)
|
||||||
|
.filter((e) => e.endsWith('.po'))
|
||||||
|
.map((l) => l.slice(0, -3));
|
||||||
|
webpackConfig = webpackConfig.concat(
|
||||||
|
langs.map((l) => buildWebpackClientConfig(false, false, l)),
|
||||||
|
);
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
webpack([webpackConfigWeb, webpackConfigClient]).run((err, stats) => {
|
webpack(webpackConfig).run((err, stats) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
import rimraf from 'rimraf';
|
import rimraf from 'rimraf';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
const builddir = path.resolve(__dirname, '../build');
|
const builddir = path.resolve(__dirname, '..', 'build');
|
||||||
|
|
||||||
|
|
||||||
function clean() {
|
function clean() {
|
||||||
|
|
|
@ -9,10 +9,10 @@ import path from 'path';
|
||||||
import glob from 'glob';
|
import glob from 'glob';
|
||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
|
|
||||||
const builddir = path.resolve(__dirname, '../build');
|
const builddir = path.resolve(__dirname, '..', 'build');
|
||||||
const deploydir = path.resolve(__dirname, '../deployment');
|
const deploydir = path.resolve(__dirname, '..', 'deployment');
|
||||||
const publicdir = path.resolve(__dirname, '../public');
|
const publicdir = path.resolve(__dirname, '..', 'public');
|
||||||
const srcdir = path.resolve(__dirname, '../src');
|
const srcdir = path.resolve(__dirname, '..', 'src');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* following functions are copied from
|
* following functions are copied from
|
||||||
|
|
|
@ -9,10 +9,10 @@ import CleanCSS from 'clean-css';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
|
|
||||||
const rootdir = path.resolve(__dirname, '..');
|
const rootdir = path.resolve(__dirname, '..');
|
||||||
const assetdir = path.resolve(__dirname, '../build/public/assets');
|
const assetdir = path.resolve(__dirname, '..', 'build', 'public', 'assets');
|
||||||
const builddir = path.resolve(__dirname, '../build');
|
const builddir = path.resolve(__dirname, '..', 'build');
|
||||||
|
|
||||||
const FOLDER = path.resolve(__dirname, '../src/styles');
|
const FOLDER = path.resolve(__dirname, '..', 'src', 'styles');
|
||||||
const FILES = [
|
const FILES = [
|
||||||
'default.css',
|
'default.css',
|
||||||
'dark.css',
|
'dark.css',
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { t } from 'ttag';
|
||||||
|
|
||||||
import { showUserAreaModal } from '../actions';
|
import { showUserAreaModal } from '../actions';
|
||||||
import NewPasswordForm from './NewPasswordForm';
|
import NewPasswordForm from './NewPasswordForm';
|
||||||
|
@ -16,7 +17,7 @@ const ForgotPasswordModal = ({ login }) => (
|
||||||
</p><br />
|
</p><br />
|
||||||
<p style={{ textAlign: 'center' }}>
|
<p style={{ textAlign: 'center' }}>
|
||||||
<NewPasswordForm back={login} />
|
<NewPasswordForm back={login} />
|
||||||
<p>Consider joining us on Guilded:
|
<p>{t`Consider joining us on Guilded:`}
|
||||||
<a href="./guilded" target="_blank">pixelplanet.fun/guilded</a>
|
<a href="./guilded" target="_blank">pixelplanet.fun/guilded</a>
|
||||||
</p>
|
</p>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -29,20 +29,33 @@ const styles = [{
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const title = 'PixelPlanet.fun 3DGlobe';
|
const title = 'PixelPlanet.fun 3DGlobe';
|
||||||
const description = '3D globe of our canvas';
|
const description = 'pixelplanet globe';
|
||||||
const scripts = [
|
const defaultScripts = assets.globe.js.map(
|
||||||
ASSET_SERVER + assets.three.js,
|
(s) => ASSET_SERVER + s,
|
||||||
ASSET_SERVER + assets.globe.js,
|
);
|
||||||
];
|
|
||||||
const body = <Globe />;
|
const body = <Globe />;
|
||||||
const globeHtml = `<!doctype html>${ReactDOM.renderToStaticMarkup(
|
|
||||||
<Html
|
|
||||||
title={title}
|
|
||||||
description={description}
|
|
||||||
scripts={scripts}
|
|
||||||
body={body}
|
|
||||||
styles={styles}
|
|
||||||
/>,
|
|
||||||
)}`;
|
|
||||||
|
|
||||||
export default globeHtml;
|
/*
|
||||||
|
* generates string with html of globe page
|
||||||
|
* @param lang language code
|
||||||
|
* @return html of mainpage
|
||||||
|
*/
|
||||||
|
function generateGlobePage(lang: string): string {
|
||||||
|
const scripts = (assets[`globe-${lang}`])
|
||||||
|
? assets[`globe-${lang}`].js.map((s) => ASSET_SERVER + s)
|
||||||
|
: defaultScripts;
|
||||||
|
|
||||||
|
const html = ReactDOM.renderToStaticMarkup(
|
||||||
|
<Html
|
||||||
|
title={title}
|
||||||
|
description={description}
|
||||||
|
scripts={scripts}
|
||||||
|
body={body}
|
||||||
|
styles={styles}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
return `<!doctype html>${html}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default generateGlobePage;
|
||||||
|
|
|
@ -22,10 +22,9 @@ let code = `window.assetserver="${ASSET_SERVER}";window.availableStyles=JSON.par
|
||||||
if (BACKUP_URL) {
|
if (BACKUP_URL) {
|
||||||
code += `window.backupurl="${BACKUP_URL}";`;
|
code += `window.backupurl="${BACKUP_URL}";`;
|
||||||
}
|
}
|
||||||
const scripts = [
|
const defaultScripts = assets.client.js.map(
|
||||||
ASSET_SERVER + assets.vendor.js,
|
(s) => ASSET_SERVER + s,
|
||||||
ASSET_SERVER + assets.client.js,
|
);
|
||||||
];
|
|
||||||
const css = [
|
const css = [
|
||||||
{
|
{
|
||||||
id: 'globcss',
|
id: 'globcss',
|
||||||
|
@ -43,6 +42,9 @@ const css = [
|
||||||
*/
|
*/
|
||||||
function generateMainPage(countryCoords: Cell, lang: string): string {
|
function generateMainPage(countryCoords: Cell, lang: string): string {
|
||||||
const [x, y] = countryCoords;
|
const [x, y] = countryCoords;
|
||||||
|
const scripts = (assets[`client-${lang}`])
|
||||||
|
? assets[`client-${lang}`].js.map((s) => ASSET_SERVER + s)
|
||||||
|
: defaultScripts;
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const html = ReactDOM.renderToStaticMarkup(
|
const html = ReactDOM.renderToStaticMarkup(
|
||||||
<Html
|
<Html
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { t } from 'ttag';
|
||||||
|
|
||||||
import { showUserAreaModal } from '../actions';
|
import { showUserAreaModal } from '../actions';
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ const RegisterModal = ({ login }) => (
|
||||||
<p className="modaltext">Register new account here</p><br />
|
<p className="modaltext">Register new account here</p><br />
|
||||||
<p style={{ textAlign: 'center' }}>
|
<p style={{ textAlign: 'center' }}>
|
||||||
<SignUpForm back={login} />
|
<SignUpForm back={login} />
|
||||||
<p>Consider joining us on Guilded:
|
<p>{t`Consider joining us on Guilded:`}
|
||||||
<a href="./guilded" target="_blank">pixelplanet.fun/guilded</a>
|
<a href="./guilded" target="_blank">pixelplanet.fun/guilded</a>
|
||||||
</p>
|
</p>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import React, { Suspense } from 'react';
|
import React, { Suspense } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { t } from 'ttag';
|
||||||
|
|
||||||
import type { State } from '../reducers';
|
import type { State } from '../reducers';
|
||||||
|
|
||||||
|
@ -124,7 +125,7 @@ const UserAreaModal = ({
|
||||||
)}
|
)}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
)}
|
)}
|
||||||
<p>Consider joining us on Guilded:
|
<p>{t`Consider joining us on Guilded:`}
|
||||||
<a href="./guilded" target="_blank">pixelplanet.fun/guilded</a>
|
<a href="./guilded" target="_blank">pixelplanet.fun/guilded</a>
|
||||||
</p>
|
</p>
|
||||||
</p>
|
</p>
|
||||||
|
|
13
src/web.js
13
src/web.js
|
@ -26,7 +26,7 @@ import {
|
||||||
admintools,
|
admintools,
|
||||||
resetPassword,
|
resetPassword,
|
||||||
} from './routes';
|
} from './routes';
|
||||||
import globeHtml from './components/Globe';
|
import generateGlobePage from './components/Globe';
|
||||||
import generateMainPage from './components/Main';
|
import generateMainPage from './components/Main';
|
||||||
|
|
||||||
import { SECOND, MONTH } from './core/constants';
|
import { SECOND, MONTH } from './core/constants';
|
||||||
|
@ -142,7 +142,7 @@ app.use('/reset_password', resetPassword);
|
||||||
// 3D Globe (react generated)
|
// 3D Globe (react generated)
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
const globeEtag = etag(
|
const globeEtag = etag(
|
||||||
`${assets.globe.js}`,
|
assets.globe.js.join('_'),
|
||||||
{ weak: true },
|
{ weak: true },
|
||||||
);
|
);
|
||||||
app.get('/globe', async (req, res) => {
|
app.get('/globe', async (req, res) => {
|
||||||
|
@ -157,7 +157,10 @@ app.get('/globe', async (req, res) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).send(globeHtml);
|
const language = req.headers['accept-language'];
|
||||||
|
const lang = (language) ? languageFromLocalisation(language) : 'en';
|
||||||
|
|
||||||
|
res.status(200).send(generateGlobePage(lang));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,7 +168,7 @@ app.get('/globe', async (req, res) => {
|
||||||
// Main Page (react generated)
|
// Main Page (react generated)
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
const indexEtag = etag(
|
const indexEtag = etag(
|
||||||
`${assets.vendor.js},${assets.client.js}`,
|
assets.client.js.join('_'),
|
||||||
{ weak: true },
|
{ weak: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -183,7 +186,7 @@ app.get('/', async (req, res) => {
|
||||||
|
|
||||||
// get start coordinates based on cloudflare header country
|
// get start coordinates based on cloudflare header country
|
||||||
const country = req.headers['cf-ipcountry'];
|
const country = req.headers['cf-ipcountry'];
|
||||||
let language = req.headers['accept-language'];
|
const language = req.headers['accept-language'];
|
||||||
|
|
||||||
const lang = (language) ? languageFromLocalisation(language) : 'en';
|
const lang = (language) ? languageFromLocalisation(language) : 'en';
|
||||||
const countryCoords = (country) ? ccToCoords(country) : [0, 0];
|
const countryCoords = (country) ? ccToCoords(country) : [0, 0];
|
||||||
|
|
|
@ -8,166 +8,185 @@ import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||||
|
|
||||||
import pkg from './package.json';
|
import pkg from './package.json';
|
||||||
|
|
||||||
const isDebug = process.argv.includes('--debug');
|
/*
|
||||||
const VERBOSE = false;
|
* Emit a file with assets paths
|
||||||
const isAnalyze = process.argv.includes('--analyze')
|
*/
|
||||||
|| process.argv.includes('--analyse');
|
const assetPlugin = new AssetsPlugin({
|
||||||
|
path: path.resolve(__dirname, 'build'),
|
||||||
|
filename: 'assets.json',
|
||||||
|
entrypoints: true,
|
||||||
|
prettyPrint: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export function buildWebpackClientConfig(development, analyze, locale) {
|
||||||
|
const ttag = {
|
||||||
|
resolve: {
|
||||||
|
translations: (locale !== 'default')
|
||||||
|
? path.resolve(__dirname, 'i18n', `${locale}.po`)
|
||||||
|
: locale,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const babelPlugins = [
|
const babelPlugins = [
|
||||||
'@babel/transform-flow-strip-types',
|
'@babel/transform-flow-strip-types',
|
||||||
['@babel/plugin-proposal-decorators', { legacy: true }],
|
['@babel/plugin-proposal-decorators', { legacy: true }],
|
||||||
'@babel/plugin-proposal-function-sent',
|
'@babel/plugin-proposal-function-sent',
|
||||||
'@babel/plugin-proposal-export-namespace-from',
|
'@babel/plugin-proposal-export-namespace-from',
|
||||||
'@babel/plugin-proposal-numeric-separator',
|
'@babel/plugin-proposal-numeric-separator',
|
||||||
'@babel/plugin-proposal-throw-expressions',
|
'@babel/plugin-proposal-throw-expressions',
|
||||||
['@babel/plugin-proposal-class-properties', { loose: true }],
|
['@babel/plugin-proposal-class-properties', { loose: true }],
|
||||||
'@babel/proposal-object-rest-spread',
|
'@babel/proposal-object-rest-spread',
|
||||||
// react-optimize
|
// react-optimize
|
||||||
'@babel/transform-react-constant-elements',
|
'@babel/transform-react-constant-elements',
|
||||||
'@babel/transform-react-inline-elements',
|
'@babel/transform-react-inline-elements',
|
||||||
'transform-react-remove-prop-types',
|
'transform-react-remove-prop-types',
|
||||||
'transform-react-pure-class-to-function',
|
'transform-react-pure-class-to-function',
|
||||||
];
|
['ttag', ttag],
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: 'client',
|
||||||
|
target: 'web',
|
||||||
|
|
||||||
export default {
|
context: __dirname,
|
||||||
name: 'client',
|
mode: (development) ? 'development' : 'production',
|
||||||
target: 'web',
|
devtool: 'source-map',
|
||||||
|
|
||||||
context: __dirname,
|
entry: {
|
||||||
mode: (isDebug) ? 'development' : 'production',
|
[(locale !== 'default') ? `client-${locale}` : 'client']:
|
||||||
devtool: 'source-map',
|
['./src/client.js'],
|
||||||
|
[(locale !== 'default') ? `globe-${locale}` : 'globe']:
|
||||||
|
['./src/globe.js'],
|
||||||
|
},
|
||||||
|
|
||||||
entry: {
|
output: {
|
||||||
client: ['./src/client.js'],
|
path: path.resolve(__dirname, 'build', 'public', 'assets'),
|
||||||
globe: ['./src/globe.js'],
|
publicPath: '/assets/',
|
||||||
},
|
filename: '[name].[chunkhash:8].js',
|
||||||
|
chunkFilename: (locale !== 'default')
|
||||||
|
? `[name]-${locale}.[chunkhash:8].js`
|
||||||
|
: '[name].[chunkhash:8].js',
|
||||||
|
},
|
||||||
|
|
||||||
output: {
|
resolve: {
|
||||||
path: path.resolve(__dirname, './build/public/assets'),
|
alias: {
|
||||||
publicPath: '/assets/',
|
ttag: 'ttag/dist/mock',
|
||||||
pathinfo: VERBOSE,
|
|
||||||
filename: isDebug ? '[name].js' : '[name].[chunkhash:8].js',
|
|
||||||
chunkFilename: isDebug ? '[name].chunk.js' : '[name].[chunkhash:8].js',
|
|
||||||
},
|
|
||||||
|
|
||||||
resolve: {
|
|
||||||
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
|
|
||||||
},
|
|
||||||
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.svg$/,
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: 'babel-loader',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
loader: 'react-svg-loader',
|
|
||||||
options: {
|
|
||||||
svgo: {
|
|
||||||
plugins: [
|
|
||||||
{
|
|
||||||
removeViewBox: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
removeDimensions: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
jsx: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
|
||||||
test: /\.(js|jsx|ts|tsx)$/,
|
},
|
||||||
loader: 'babel-loader',
|
|
||||||
include: [
|
module: {
|
||||||
path.resolve(__dirname, './src'),
|
rules: [
|
||||||
],
|
{
|
||||||
options: {
|
test: /\.svg$/,
|
||||||
cacheDirectory: isDebug,
|
use: [
|
||||||
babelrc: false,
|
{
|
||||||
presets: [
|
loader: 'babel-loader',
|
||||||
['@babel/preset-env', {
|
},
|
||||||
targets: {
|
{
|
||||||
browsers: pkg.browserslist,
|
loader: 'react-svg-loader',
|
||||||
|
options: {
|
||||||
|
svgo: {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
removeViewBox: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
removeDimensions: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
jsx: false,
|
||||||
},
|
},
|
||||||
modules: false,
|
},
|
||||||
useBuiltIns: 'usage',
|
|
||||||
corejs: {
|
|
||||||
version: 3,
|
|
||||||
},
|
|
||||||
debug: false,
|
|
||||||
}],
|
|
||||||
'@babel/typescript',
|
|
||||||
'@babel/react',
|
|
||||||
],
|
],
|
||||||
plugins: babelPlugins,
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
test: /\.(js|jsx|ts|tsx)$/,
|
||||||
test: /\.css/,
|
loader: 'babel-loader',
|
||||||
use: ['style-loader',
|
include: [
|
||||||
{
|
path.resolve(__dirname, 'src'),
|
||||||
loader: 'css-loader',
|
],
|
||||||
options: {
|
options: {
|
||||||
sourceMap: isDebug,
|
cacheDirectory: development,
|
||||||
modules: false,
|
babelrc: false,
|
||||||
},
|
presets: [
|
||||||
|
['@babel/preset-env', {
|
||||||
|
targets: {
|
||||||
|
browsers: pkg.browserslist,
|
||||||
|
},
|
||||||
|
modules: false,
|
||||||
|
useBuiltIns: 'usage',
|
||||||
|
corejs: {
|
||||||
|
version: 3,
|
||||||
|
},
|
||||||
|
debug: false,
|
||||||
|
}],
|
||||||
|
'@babel/typescript',
|
||||||
|
'@babel/react',
|
||||||
|
],
|
||||||
|
plugins: babelPlugins,
|
||||||
},
|
},
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
plugins: [
|
|
||||||
// Define free variables
|
|
||||||
// https://webpack.github.io/docs/list-of-plugins.html#defineplugin
|
|
||||||
new webpack.DefinePlugin({
|
|
||||||
'process.env.NODE_ENV': isDebug ? '"development"' : '"production"',
|
|
||||||
'process.env.BROWSER': true,
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Emit a file with assets paths
|
|
||||||
// https://github.com/sporto/assets-webpack-plugin#options
|
|
||||||
new AssetsPlugin({
|
|
||||||
path: path.resolve(__dirname, './build'),
|
|
||||||
filename: 'assets.json',
|
|
||||||
prettyPrint: true,
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Webpack Bundle Analyzer
|
|
||||||
// https://github.com/th0r/webpack-bundle-analyzer
|
|
||||||
...isAnalyze ? [new BundleAnalyzerPlugin()] : [],
|
|
||||||
],
|
|
||||||
|
|
||||||
optimization: {
|
|
||||||
splitChunks: {
|
|
||||||
chunks: 'all',
|
|
||||||
name: false,
|
|
||||||
cacheGroups: {
|
|
||||||
default: false,
|
|
||||||
defaultVendors: false,
|
|
||||||
|
|
||||||
vendor: {
|
|
||||||
name: 'vendor',
|
|
||||||
chunks: (chunk) => chunk.name === 'client',
|
|
||||||
test: /node_modules/,
|
|
||||||
},
|
},
|
||||||
three: {
|
{
|
||||||
test: /[\\/]node_modules[\\/]three[\\/]/,
|
test: /\.css/,
|
||||||
name: 'three',
|
use: ['style-loader',
|
||||||
chunks: 'all',
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: {
|
||||||
|
sourceMap: development,
|
||||||
|
modules: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
// Define free variables
|
||||||
|
// https://webpack.github.io/docs/list-of-plugins.html#defineplugin
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': development ? '"development"' : '"production"',
|
||||||
|
'process.env.BROWSER': true,
|
||||||
|
}),
|
||||||
|
|
||||||
|
assetPlugin,
|
||||||
|
|
||||||
|
// Webpack Bundle Analyzer
|
||||||
|
// https://github.com/th0r/webpack-bundle-analyzer
|
||||||
|
...analyze ? [new BundleAnalyzerPlugin({ analyzerPort: 8889 })] : [],
|
||||||
|
],
|
||||||
|
|
||||||
|
optimization: {
|
||||||
|
splitChunks: {
|
||||||
|
chunks: 'all',
|
||||||
|
name: false,
|
||||||
|
cacheGroups: {
|
||||||
|
default: false,
|
||||||
|
defaultVendors: false,
|
||||||
|
|
||||||
|
vendor: {
|
||||||
|
name: 'vendor',
|
||||||
|
chunks: (chunk) => chunk.name.startsWith('client'),
|
||||||
|
test: /[\\/]node_modules[\\/]/,
|
||||||
|
},
|
||||||
|
three: {
|
||||||
|
name: 'three',
|
||||||
|
chunks: 'all',
|
||||||
|
test: /[\\/]node_modules[\\/]three[\\/]/,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
|
|
||||||
bail: !isDebug,
|
cache: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default buildWebpackClientConfig(
|
||||||
|
process.argv.includes('--debug'),
|
||||||
|
process.argv.includes('--analyse') || process.argv.includes('--analyze'),
|
||||||
|
'default',
|
||||||
|
);
|
||||||
|
|
||||||
cache: isDebug,
|
|
||||||
};
|
|
||||||
|
|
237
webpack.config.client.babel.js.old
Normal file
237
webpack.config.client.babel.js.old
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import webpack from 'webpack';
|
||||||
|
import AssetsPlugin from 'assets-webpack-plugin';
|
||||||
|
import TtagWebpackPlugin from 'ttag-webpack-plugin';
|
||||||
|
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||||
|
|
||||||
|
import pkg from './package.json';
|
||||||
|
|
||||||
|
const isDebug = process.argv.includes('--debug');
|
||||||
|
const VERBOSE = false;
|
||||||
|
const isAnalyze = process.argv.includes('--analyze')
|
||||||
|
|| process.argv.includes('--analyse');
|
||||||
|
|
||||||
|
// activate for deprecation tracking
|
||||||
|
// process.traceDeprecation = true;
|
||||||
|
|
||||||
|
const babelPlugins = [
|
||||||
|
'@babel/transform-flow-strip-types',
|
||||||
|
['@babel/plugin-proposal-decorators', { legacy: true }],
|
||||||
|
'@babel/plugin-proposal-function-sent',
|
||||||
|
'@babel/plugin-proposal-export-namespace-from',
|
||||||
|
'@babel/plugin-proposal-numeric-separator',
|
||||||
|
'@babel/plugin-proposal-throw-expressions',
|
||||||
|
['@babel/plugin-proposal-class-properties', { loose: true }],
|
||||||
|
'@babel/proposal-object-rest-spread',
|
||||||
|
// react-optimize
|
||||||
|
'@babel/transform-react-constant-elements',
|
||||||
|
'@babel/transform-react-inline-elements',
|
||||||
|
'transform-react-remove-prop-types',
|
||||||
|
'transform-react-pure-class-to-function',
|
||||||
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get all available languages
|
||||||
|
*/
|
||||||
|
const langDir = path.resolve(__dirname, 'i18n');
|
||||||
|
const langs = fs.readdirSync(langDir)
|
||||||
|
.filter((e) => e.endsWith('.po'))
|
||||||
|
.map((l) => l.slice(0, -3));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create list of translations for ttag-webpack-plugin
|
||||||
|
*/
|
||||||
|
const translations = {};
|
||||||
|
for (let i = 0; i < langs.length; i += 1) {
|
||||||
|
const lang = langs[i];
|
||||||
|
translations[lang] = path.resolve(langDir, `${lang}.po`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cache Groups for splitChunks
|
||||||
|
* (edit cache groups here, make sure that chunks is based on name)
|
||||||
|
*/
|
||||||
|
const cacheGroups = {
|
||||||
|
default: false,
|
||||||
|
defaultVendors: false,
|
||||||
|
|
||||||
|
vendor: {
|
||||||
|
name: 'vendor',
|
||||||
|
chunks: (chunk) => chunk.name === 'client',
|
||||||
|
test: /[\\/]node_modules[\\/]/,
|
||||||
|
},
|
||||||
|
three: {
|
||||||
|
name: 'three',
|
||||||
|
chunks: (chunk) => (chunk.name === 'globe' || chunk.name === 'voxel'),
|
||||||
|
test: /[\\/]node_modules[\\/]three[\\/]/,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* automatically add Cache Groups for languages based on
|
||||||
|
* manually set cacheGroups
|
||||||
|
*/
|
||||||
|
const groups = Object.keys(cacheGroups);
|
||||||
|
for (let u = 0; u < groups.length; u += 1) {
|
||||||
|
const group = cacheGroups[groups[u]];
|
||||||
|
if (!group.test) continue;
|
||||||
|
|
||||||
|
for (let i = 0; i < langs.length; i += 1) {
|
||||||
|
const lang = langs[i];
|
||||||
|
/* add lang */
|
||||||
|
const key = `${groups[u]}-${lang}`;
|
||||||
|
const name = `${group.name}-${lang}`;
|
||||||
|
const { test, chunks } = group;
|
||||||
|
|
||||||
|
cacheGroups[key] = {
|
||||||
|
name,
|
||||||
|
chunks: (chunk) => {
|
||||||
|
if (!chunk.name.endsWith(`-${lang}`)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return chunks({
|
||||||
|
name: chunk.name.slice(0, -lang.length - 1),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
test,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'client',
|
||||||
|
target: 'web',
|
||||||
|
|
||||||
|
context: __dirname,
|
||||||
|
mode: (isDebug) ? 'development' : 'production',
|
||||||
|
devtool: 'source-map',
|
||||||
|
|
||||||
|
entry: {
|
||||||
|
client: ['./src/client.js'],
|
||||||
|
globe: ['./src/globe.js'],
|
||||||
|
},
|
||||||
|
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, 'build', 'public', 'assets'),
|
||||||
|
publicPath: '/assets/',
|
||||||
|
pathinfo: VERBOSE,
|
||||||
|
filename: isDebug ? '[name].js' : '[name].[chunkhash:8].js',
|
||||||
|
chunkFilename: isDebug ? '[name].chunk.js' : '[name].[chunkhash:8].js',
|
||||||
|
},
|
||||||
|
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
|
||||||
|
},
|
||||||
|
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.svg$/,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: 'babel-loader',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: 'react-svg-loader',
|
||||||
|
options: {
|
||||||
|
svgo: {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
removeViewBox: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
removeDimensions: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
jsx: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(js|jsx|ts|tsx)$/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
include: [
|
||||||
|
path.resolve(__dirname, 'src'),
|
||||||
|
],
|
||||||
|
options: {
|
||||||
|
cacheDirectory: isDebug,
|
||||||
|
babelrc: false,
|
||||||
|
presets: [
|
||||||
|
['@babel/preset-env', {
|
||||||
|
targets: {
|
||||||
|
browsers: pkg.browserslist,
|
||||||
|
},
|
||||||
|
modules: false,
|
||||||
|
useBuiltIns: 'usage',
|
||||||
|
corejs: {
|
||||||
|
version: 3,
|
||||||
|
},
|
||||||
|
debug: false,
|
||||||
|
}],
|
||||||
|
'@babel/typescript',
|
||||||
|
'@babel/react',
|
||||||
|
],
|
||||||
|
plugins: babelPlugins,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css/,
|
||||||
|
use: ['style-loader',
|
||||||
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: {
|
||||||
|
sourceMap: isDebug,
|
||||||
|
modules: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
// Define free variables
|
||||||
|
// https://webpack.github.io/docs/list-of-plugins.html#defineplugin
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': isDebug ? '"development"' : '"production"',
|
||||||
|
'process.env.BROWSER': true,
|
||||||
|
}),
|
||||||
|
|
||||||
|
// make multiple bundles for each language
|
||||||
|
new TtagWebpackPlugin({
|
||||||
|
translations,
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Emit a file with assets paths
|
||||||
|
// https://github.com/sporto/assets-webpack-plugin#options
|
||||||
|
new AssetsPlugin({
|
||||||
|
path: path.resolve(__dirname, 'build'),
|
||||||
|
filename: 'assets.json',
|
||||||
|
prettyPrint: true,
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Webpack Bundle Analyzer
|
||||||
|
// https://github.com/th0r/webpack-bundle-analyzer
|
||||||
|
...isAnalyze ? [new BundleAnalyzerPlugin()] : [],
|
||||||
|
],
|
||||||
|
|
||||||
|
optimization: {
|
||||||
|
splitChunks: {
|
||||||
|
chunks: 'all',
|
||||||
|
name: false,
|
||||||
|
cacheGroups,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
bail: !isDebug,
|
||||||
|
|
||||||
|
cache: isDebug,
|
||||||
|
};
|
|
@ -9,7 +9,6 @@ import GeneratePackageJsonPlugin from 'generate-package-json-webpack-plugin';
|
||||||
import pkg from './package.json';
|
import pkg from './package.json';
|
||||||
|
|
||||||
const isDebug = process.argv.includes('--debug');
|
const isDebug = process.argv.includes('--debug');
|
||||||
const VERBOSE = false;
|
|
||||||
|
|
||||||
const basePackageValues = {
|
const basePackageValues = {
|
||||||
name: pkg.name,
|
name: pkg.name,
|
||||||
|
@ -54,8 +53,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
pathinfo: VERBOSE,
|
path: path.resolve(__dirname, 'build'),
|
||||||
path: path.resolve(__dirname, './build'),
|
|
||||||
libraryTarget: 'commonjs2',
|
libraryTarget: 'commonjs2',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -69,7 +67,7 @@ export default {
|
||||||
test: /\.(js|jsx|ts|tsx)$/,
|
test: /\.(js|jsx|ts|tsx)$/,
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
include: [
|
include: [
|
||||||
path.resolve(__dirname, './src'),
|
path.resolve(__dirname, 'src'),
|
||||||
],
|
],
|
||||||
options: {
|
options: {
|
||||||
cacheDirectory: isDebug,
|
cacheDirectory: isDebug,
|
||||||
|
@ -121,9 +119,8 @@ export default {
|
||||||
}),
|
}),
|
||||||
// create package.json for deployment
|
// create package.json for deployment
|
||||||
new GeneratePackageJsonPlugin(basePackageValues, {
|
new GeneratePackageJsonPlugin(basePackageValues, {
|
||||||
debug: VERBOSE,
|
|
||||||
sourcePackageFilenames: [
|
sourcePackageFilenames: [
|
||||||
path.resolve(__dirname, './package.json'),
|
path.resolve(__dirname, 'package.json'),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -133,8 +130,4 @@ export default {
|
||||||
__filename: false,
|
__filename: false,
|
||||||
__dirname: false,
|
__dirname: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
bail: !isDebug,
|
|
||||||
|
|
||||||
cache: isDebug,
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user