From 4d55f51feeb50a8fdf36f1345ba5063b5d27afc5 Mon Sep 17 00:00:00 2001 From: Ildar Kamalov Date: Fri, 31 Jan 2020 15:57:20 +0300 Subject: [PATCH] + client: remove locales from js bundle --- .twosky.json | 8 +- client/.eslintrc | 5 + client/package-lock.json | 143 ++++++++++++++++++++++++++--- client/package.json | 1 + client/src/components/ui/Footer.js | 10 +- client/src/helpers/constants.js | 111 ---------------------- client/src/helpers/twosky.js | 6 ++ client/src/i18n.js | 127 ++----------------------- client/webpack.common.js | 14 ++- 9 files changed, 177 insertions(+), 248 deletions(-) create mode 100644 client/src/helpers/twosky.js diff --git a/.twosky.json b/.twosky.json index 8ad2a205..c1dcf2f9 100644 --- a/.twosky.json +++ b/.twosky.json @@ -7,29 +7,29 @@ "da": "Dansk", "de": "Deutsch", "nl": "Dutch", - "no": "Norsk", "en": "English", "es": "Español", "fr": "Français", + "hr": "Hrvatski", "id": "Indonesian", "it": "Italiano", + "no": "Norsk", "pl": "Polski", "pt-br": "Portuguese (BR)", "pt-pt": "Portuguese (PT)", "sk": "Slovenčina", "sl": "Slovenščina", + "sr-cs": "Srpski", "sv": "Svenska", "vi": "Tiếng Việt", "tr": "Türkçe", "cs": "Český", "bg": "Български", "ru": "Русский", + "fa": "فارسی", "ja": "日本語", "zh-tw": "正體中文", "zh-cn": "简体中文", - "sr-cs": "Srpski", - "hr": "Hrvatski", - "fa": "فارسی", "ko": "한국어" } } diff --git a/client/.eslintrc b/client/.eslintrc index d5d5955b..56b5a7a6 100644 --- a/client/.eslintrc +++ b/client/.eslintrc @@ -17,6 +17,11 @@ "react": { "pragma": "React", "version": "16.4" + }, + "import/resolver": { + "webpack": { + "config": "webpack.common.js" + } } }, diff --git a/client/package-lock.json b/client/package-lock.json index 81899b0c..d0ec7a06 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -925,6 +925,12 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, + "array-find": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz", + "integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=", + "dev": true + }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -4548,6 +4554,79 @@ } } }, + "eslint-import-resolver-webpack": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.12.1.tgz", + "integrity": "sha512-O/sUAXk6GWrICiN8JUkkjdt9uZpqZHP+FVnTxtEILL6EZMaPSrnP4lGPSFwcKsv7O211maqq4Nz60+dh236hVg==", + "dev": true, + "requires": { + "array-find": "^1.0.0", + "debug": "^2.6.9", + "enhanced-resolve": "^0.9.1", + "find-root": "^1.1.0", + "has": "^1.0.3", + "interpret": "^1.2.0", + "lodash": "^4.17.15", + "node-libs-browser": "^1.0.0 || ^2.0.0", + "resolve": "^1.13.1", + "semver": "^5.7.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "enhanced-resolve": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", + "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.2.0", + "tapable": "^0.1.8" + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "memory-fs": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", + "integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=", + "dev": true + }, + "resolve": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz", + "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "tapable": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", + "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=", + "dev": true + } + } + }, "eslint-loader": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-1.9.0.tgz", @@ -5458,7 +5537,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -5479,12 +5559,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5499,17 +5581,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5626,7 +5711,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5638,6 +5724,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5652,6 +5739,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5659,12 +5747,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5683,6 +5773,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5763,7 +5854,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5775,6 +5867,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5860,7 +5953,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5896,6 +5990,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5915,6 +6010,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5958,12 +6054,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -6778,6 +6876,29 @@ "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-2.2.3.tgz", "integrity": "sha512-sJZ2n9Vgax0vGer23hJMwyO3FRO7P0dq2DXZPXWE329g3snfJUcw+S24Mp3lqJaxL/0McDu4BD75ds6pzIfhhw==" }, + "i18next-xhr-backend": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/i18next-xhr-backend/-/i18next-xhr-backend-3.2.2.tgz", + "integrity": "sha512-OtRf2Vo3IqAxsttQbpjYnmMML12IMB5e0fc5B7qKJFLScitYaXa1OhMX0n0X/3vrfFlpHL9Ro/H+ps4Ej2j7QQ==", + "requires": { + "@babel/runtime": "^7.5.5" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", + "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", diff --git a/client/package.json b/client/package.json index b2be9b5b..026692eb 100644 --- a/client/package.json +++ b/client/package.json @@ -15,6 +15,7 @@ "date-fns": "^1.29.0", "i18next": "^12.0.0", "i18next-browser-languagedetector": "^2.2.3", + "i18next-xhr-backend": "^3.2.2", "lodash": "^4.17.15", "nanoid": "^1.2.3", "prop-types": "^15.7.2", diff --git a/client/src/components/ui/Footer.js b/client/src/components/ui/Footer.js index b61058d4..8174ba2d 100644 --- a/client/src/components/ui/Footer.js +++ b/client/src/components/ui/Footer.js @@ -1,7 +1,9 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Trans, withNamespaces } from 'react-i18next'; -import { REPOSITORY, LANGUAGES, PRIVACY_POLICY_LINK } from '../../helpers/constants'; + +import { REPOSITORY, PRIVACY_POLICY_LINK } from '../../helpers/constants'; +import { LANGUAGES } from '../../helpers/twosky'; import i18n from '../../i18n'; import Version from './Version'; @@ -68,9 +70,9 @@ class Footer extends Component { value={i18n.language} onChange={this.changeLanguage} > - {LANGUAGES.map(language => ( - ))} diff --git a/client/src/helpers/constants.js b/client/src/helpers/constants.js index 5920552c..2c457736 100644 --- a/client/src/helpers/constants.js +++ b/client/src/helpers/constants.js @@ -31,117 +31,6 @@ export const REPOSITORY = { export const PRIVACY_POLICY_LINK = 'https://adguard.com/privacy/home.html'; -export const LANGUAGES = [ - { - key: 'da', - name: 'Dansk', - }, - { - key: 'de', - name: 'Deutsch', - }, - { - key: 'nl', - name: 'Dutch', - }, - { - key: 'en', - name: 'English', - }, - { - key: 'es', - name: 'Español', - }, - { - key: 'fr', - name: 'Français', - }, - { - key: 'id', - name: 'Indonesian', - }, - { - key: 'it', - name: 'Italiano', - }, - { - key: 'pl', - name: 'Polski', - }, - { - key: 'pt-br', - name: 'Portuguese (BR)', - }, - { - key: 'pt-pt', - name: 'Portuguese (PT)', - }, - { - key: 'sk', - name: 'Slovenčina', - }, - { - key: 'sl', - name: 'Slovenščina', - }, - { - key: 'sv', - name: 'Svenska', - }, - { - key: 'vi', - name: 'Tiếng Việt', - }, - { - key: 'tr', - name: 'Türkçe', - }, - { - key: 'cs', - name: 'Český', - }, - { - key: 'bg', - name: 'Български', - }, - { - key: 'ru', - name: 'Русский', - }, - { - key: 'ja', - name: '日本語', - }, - { - key: 'zh-tw', - name: '正體中文', - }, - { - key: 'zh-cn', - name: '简体中文', - }, - { - key: 'no', - name: 'Norsk', - }, - { - key: 'sr-cs', - name: 'Srpski', - }, - { - key: 'hr', - name: 'Hrvatski', - }, - { - key: 'fa', - name: 'فارسی', - }, - { - key: 'ko', - name: '한국어', - }, -]; - export const INSTALL_FIRST_STEP = 1; export const INSTALL_TOTAL_STEPS = 5; diff --git a/client/src/helpers/twosky.js b/client/src/helpers/twosky.js new file mode 100644 index 00000000..d9534ba6 --- /dev/null +++ b/client/src/helpers/twosky.js @@ -0,0 +1,6 @@ +import twosky from 'MainRoot/.twosky.json'; + +export const { + languages: LANGUAGES, + base_locale: BASE_LOCALE, +} = twosky[0]; diff --git a/client/src/i18n.js b/client/src/i18n.js index 6f13536a..afc3b65b 100644 --- a/client/src/i18n.js +++ b/client/src/i18n.js @@ -1,132 +1,21 @@ import i18n from 'i18next'; +import XHR from 'i18next-xhr-backend'; import { reactI18nextModule } from 'react-i18next'; import { initReactI18n } from 'react-i18next/hooks'; import langDetect from 'i18next-browser-languagedetector'; -import { DEFAULT_LANGUAGE } from './helpers/constants'; +import { LANGUAGES, BASE_LOCALE } from './helpers/twosky'; -import vi from './__locales/vi.json'; -import en from './__locales/en.json'; -import ru from './__locales/ru.json'; -import es from './__locales/es.json'; -import fr from './__locales/fr.json'; -import ja from './__locales/ja.json'; -import sv from './__locales/sv.json'; -import ptBR from './__locales/pt-br.json'; -import zhTW from './__locales/zh-tw.json'; -import bg from './__locales/bg.json'; -import zhCN from './__locales/zh-cn.json'; -import cs from './__locales/cs.json'; -import da from './__locales/da.json'; -import de from './__locales/de.json'; -import id from './__locales/id.json'; -import it from './__locales/it.json'; -import ko from './__locales/ko.json'; -import no from './__locales/no.json'; -import nl from './__locales/nl.json'; -import pl from './__locales/pl.json'; -import ptPT from './__locales/pt-pt.json'; -import sk from './__locales/sk.json'; -import sl from './__locales/sl.json'; -import tr from './__locales/tr.json'; -import srCS from './__locales/sr-cs.json'; -import hr from './__locales/hr.json'; -import fa from './__locales/fa.json'; - -const resources = { - en: { - translation: en, - }, - vi: { - translation: vi, - }, - ru: { - translation: ru, - }, - es: { - translation: es, - }, - fr: { - translation: fr, - }, - ja: { - translation: ja, - }, - sv: { - translation: sv, - }, - 'pt-br': { - translation: ptBR, - }, - 'zh-tw': { - translation: zhTW, - }, - bg: { - translation: bg, - }, - 'zh-cn': { - translation: zhCN, - }, - cs: { - translation: cs, - }, - da: { - translation: da, - }, - de: { - translation: de, - }, - id: { - translation: id, - }, - it: { - translation: it, - }, - ko: { - translation: ko, - }, - no: { - translation: no, - }, - nl: { - translation: nl, - }, - pl: { - translation: pl, - }, - 'pt-pt': { - translation: ptPT, - }, - sk: { - translation: sk, - }, - sl: { - translation: sl, - }, - tr: { - translation: tr, - }, - 'sr-cs': { - translation: srCS, - }, - hr: { - translation: hr, - }, - fa: { - translation: fa, - }, -}; - -const availableLanguages = Object.keys(resources); +const availableLanguages = Object.keys(LANGUAGES); i18n .use(langDetect) + .use(XHR) .use(initReactI18n) .use(reactI18nextModule) .init({ - resources, lowerCaseLng: true, - fallbackLng: DEFAULT_LANGUAGE, + fallbackLng: BASE_LOCALE, keySeparator: false, nsSeparator: false, returnEmptyString: false, @@ -136,9 +25,13 @@ i18n react: { wait: true, }, + whitelist: availableLanguages, + backend: { + loadPath: '/__locales/{{lng}}.json', + }, }, () => { if (!availableLanguages.includes(i18n.language)) { - i18n.changeLanguage(DEFAULT_LANGUAGE); + i18n.changeLanguage(BASE_LOCALE); } }); diff --git a/client/webpack.common.js b/client/webpack.common.js index 32248b14..db61ea17 100644 --- a/client/webpack.common.js +++ b/client/webpack.common.js @@ -15,6 +15,7 @@ const HTML_PATH = path.resolve(RESOURCES_PATH, 'public/index.html'); const HTML_INSTALL_PATH = path.resolve(RESOURCES_PATH, 'public/install.html'); const HTML_LOGIN_PATH = path.resolve(RESOURCES_PATH, 'public/login.html'); const FAVICON_PATH = path.resolve(RESOURCES_PATH, 'public/favicon.png'); +const LOCALES_PATH = path.resolve(RESOURCES_PATH, 'src/__locales/*.json'); const PUBLIC_PATH = path.resolve(__dirname, '../build/static'); @@ -32,6 +33,10 @@ const config = { }, resolve: { modules: ['node_modules'], + alias: { + MainRoot: path.resolve(__dirname, '../'), + ClientRoot: path.resolve(__dirname, './src'), + }, }, module: { rules: [ @@ -101,7 +106,7 @@ const config = { new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), }), - new CleanWebpackPlugin(['*.*'], { + new CleanWebpackPlugin(['**/*.*'], { root: PUBLIC_PATH, verbose: false, dry: false, @@ -132,6 +137,13 @@ const config = { new CopyPlugin([ { from: FAVICON_PATH, to: PUBLIC_PATH }, ]), + new CopyPlugin([ + { + from: LOCALES_PATH, + to: PUBLIC_PATH, + context: 'src/', + }, + ]), ], };