in React
π¨π»
bg fr lt sk zh cs hr lv sl zh-hans da ht mk sm de hu mn sq el hy ms sr en id nl sv eo is no th es it pl to et ja pt tr fi km ro uk fj ko ru vi
en 1KB gzip
all
~45KB gzip
import i18n from "i18next";
import {initReactI18next} from 'react-i18next'
import localeStrings from './allLocaleStrings.json'
i18n
.use(initReactI18next)
.init({
lng: "zh",
fallbackLng: "en",
resources: localeStrings
});
import React from 'react'
import './i18n'
import { useTranslation } from "react-i18next";
export default function App(){
const { t } = useTranslation();
return <div>{t("title")}</div>
}
i18n.js
App.js
import i18n from "i18next";
export const addTranslations = (translations) => {
translations.forEach(locale=>{
i18n.addResources(locale, 'translation', translations[locale])
})
}
// ... lots of other stuff too
import React from 'react'
import { addTranslations } from '@fs/zion-locale'
import { useTranslation } from "react-i18next";
import translations from './locales'
addTranslations(translations)
export default function App(){
const { t } = useTranslation();
return <div>{t("title")}</div>
}
@fs/zion-locale
App.js
// App.js
import React from "react";
import translations from "./locales";
import { addTranslations } from "@fs/zion-locale";
import { useTranslation } from "react-i18next";
addTranslations(translations);
export default function App() {
const [t] = useTranslation();
return (
<div>
<h1>{t("overview")}</h1>
</div>
);
}
{
"overview": "Overview"
}
// intentionally left blank
.
βββ App.js
βββ node_modules
β βββ @fs
β βββ zion-locale
β βββ locales
β βββ de
β β βββ common-ui.json
β β βββ translation.json
β βββ en
β β βββ common-ui.json
β β βββ translation.json
β βββ es
β β βββ common-ui.json
β β βββ translation.json
β βββ index.js
βββ locales
βββ de
β βββ translation.json
βββ en
β βββ translation.json
βββ es
β βββ translation.json
βββ index.js
export default {
de: {
overview: "Γberblick"
},
en: {
overview: "Overview"
},
es: {
overview: "VisiΓ³n general"
}
};
// intentionally left blank
.
βββ App.js
βββ node_modules
β βββ @fs
β βββ zion-locale
β βββ locales
β βββ de
β β βββ common-ui.json
β β βββ translation.json
β βββ en
β β βββ common-ui.json
β β βββ translation.json
β βββ es
β β βββ common-ui.json
β β βββ translation.json
β βββ index.js
βββ locales
βββ de
β βββ translation.json
βββ en
β βββ translation.json
βββ es
β βββ translation.json
βββ index.js
export default {
de: {
overview: "Γberblick"
},
en: {
overview: "Overview"
},
es: {
overview: "VisiΓ³n general"
}
};
// App.js
import React from "react";
import translations from "./locales";
import { addTranslations } from "@fs/zion-locale";
import { useTranslation } from "react-i18next";
addTranslations(translations);
export default function App() {
const [t] = useTranslation();
return (
<div>
<h1>{t("overview")}</h1>
</div>
);
}
(It's a module bundler)
add.js
index.js
subtract.js
bundle.js
import add from './add.js';
import subtract from './subtract.js';
console.log(`Add: ${add(4,5)}`);
console.log(`Subtract: ${subtract(9,5)}`);
const add = (a, b) => {
return a + b;
}
export default add;
const subtract = (a, b) => {
return a - b;
}
export default subtract;
index.js
add.js
subtract.js
const add = (a, b) => {
return a + b;
}
const subtract = (a, b) => {
return a - b;
}
console.log(`Add: ${add(4,5)}`);
console.log(`Subtract: ${subtract(9,5)}`);
bundle.js
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/add.js":
/*!********************!*\
!*** ./src/add.js ***!
\********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => /* binding */ add\n/* harmony export */ });\nfunction add(a, b) {\n return a + b;\n}\n\n\n//# sourceURL=webpack://basic-webpack/./src/add.js?");
/***/ }),
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _subtract__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./subtract */ \"./src/subtract.js\");\n/* harmony import */ var _add__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./add */ \"./src/add.js\");\n\n\n\nconsole.log((0,_subtract__WEBPACK_IMPORTED_MODULE_0__.default)(10,4))\nconsole.log((0,_add__WEBPACK_IMPORTED_MODULE_1__.default)(10,4))\n\n\n//# sourceURL=webpack://basic-webpack/./src/index.js?");
/***/ }),
/***/ "./src/subtract.js":
/*!*************************!*\
!*** ./src/subtract.js ***!
\*************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => /* binding */ subtract\n/* harmony export */ });\nfunction subtract(a, b) {\n return a - b;\n}\n\n\n//# sourceURL=webpack://basic-webpack/./src/subtract.js?");
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(__webpack_module_cache__[moduleId]) {
/******/ return __webpack_module_cache__[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
/******/ // startup
/******/ // Load entry module
/******/ __webpack_require__("./src/index.js");
/******/ // This entry module used 'exports' so it can't be inlined
/******/ })()
;
bundle.js
module.exports = {
entry: './src/index.js',
output: {
path: '/dist',
filename: 'bundle.js'
}
}
module.exports = {
entry: './src/index.js',
output: {
path: '/dist',
filename: 'bundle.js'
}
}
module.exports = {
entry: './src/index.js',
output: {
path: '/dist',
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'my-replace-loader'
}
}
]
}
}
module.exports = function(source) {
source = source.replace(/stuff/g, "things");
return source;
};
items.map(item=>{
return item.replace('stuff','thing');
});
Remind's me of a map function
export default function(){
const stuff = 'stuff'
console.log(stuff)
}
export default function(){
const things = 'things'
console.log(things)
}
add.js
index.js
subtract.js
bundle.js
my-replace-loader
once for each file
module.exports = {
entry: './src/index.js',
output: {
path: '/dist',
filename: 'bundle.js'
},
module: {
rules: [
{
test: /locales/,
use: {
loader: 'alienfast/i18next-loader'
}
}
]
}
}
export default {
de: {
overview: "Γberblick"
},
en: {
overview: "Overview"
},
es: {
overview: "VisiΓ³n general"
}
};
// intentionally left blank
.
βββ App.js
βββ node_modules
β βββ @fs
β βββ zion-locale
β βββ locales
β βββ de
β β βββ common-ui.json
β β βββ translation.json
β βββ en
β β βββ common-ui.json
β β βββ translation.json
β βββ es
β β βββ common-ui.json
β β βββ translation.json
β βββ index.js
βββ locales
βββ de
β βββ translation.json
βββ en
β βββ translation.json
βββ es
β βββ translation.json
βββ index.js
const jsonfile = require("jsonfile");
module.exports = function() {
const allLocales = getDirectoryNames();
const bundle = {};
//['en','de','es'].forEach
allLocales.forEach(locale => {
bundle[locale] = jsonfile.readFileSync(`./${locale}/translation.json`);
});
return "export default " + JSON.stringify(bundle);
};
.
βββ App.js
βββ node_modules
β βββ @fs
β βββ zion-locale
β βββ locales
β βββ de
β β βββ common-ui.json
β β βββ translation.json
β βββ en
β β βββ common-ui.json
β β βββ translation.json
β βββ es
β β βββ common-ui.json
β β βββ translation.json
β βββ index.js
βββ locales
βββ de
β βββ translation.json
βββ en
β βββ translation.json
βββ es
β βββ translation.json
βββ index.js
export default {
de: {
overview: "Γberblick"
},
en: {
overview: "Overview"
},
es: {
overview: "VisiΓ³n general"
}
};
alienfast/i18next-loader.js
export default {
de: {
overview: "Γberblick"
},
en: {
overview: "Overview"
},
es: {
overview: "VisiΓ³n general"
}
};
import i18n from 'i18next'
import(`./locales/${i18n.language}/translation.json`)
.then(localeStrings => {
i18n.addResources(i18n.language, 'translation', localeStrings)
})
import i18n from 'i18next'
import(`./locales/${i18n.language}/translation.json`)
.then(localeStrings => {
i18n.addResources(i18n.language, 'translation', localeStrings)
})
.
βββ App.js
βββ node_modules
β βββ @fs
β βββ zion-locale
β βββ locales
β βββ de
β β βββ common-ui.json
β β βββ translation.json
β βββ en
β β βββ common-ui.json
β β βββ translation.json
β βββ es
β β βββ common-ui.json
β β βββ translation.json
β βββ index.js
βββ locales
βββ de
β βββ translation.json
βββ en
β βββ translation.json
βββ es
β βββ translation.json
βββ index.js
module.exports = function() {
return `
import i18n from 'i18next'
import(\`./locales/${i18n.language}/translation.json\`)
.then(localeStrings => {
i18n.addResources(i18n.language, 'translation', localeStrings)
})
`
};
// intentionally left blank
// App.js
import React from "react";
import "./locales";
import { useTranslation } from "react-i18next";
export default function App() {
const [t] = useTranslation();
return (
<div>
<h1>{t("overview")}</h1>
</div>
);
}
// App.js
import React from "react";
import /*translations from*/ "./locales";
// import { addTranslations } from "@fs/zion-locale";
import { useTranslation } from "react-i18next";
// addTranslations(translations);
export default function App() {
const [t] = useTranslation();
return (
<div>
<h1>{t("overview")}</h1>
</div>
);
}
// App.js
import React from "react";
import translations from "./locales";
import { addTranslations } from "@fs/zion-locale";
import { useTranslation } from "react-i18next";
addTranslations(translations);
export default function App() {
const [t] = useTranslation();
return (
<div>
<h1>{t("overview")}</h1>
</div>
);
}
.
βββ App.js
βββ locales
Β Β βββ de
Β Β β βββ translation.json
Β Β βββ en
Β Β β βββ translation.json
Β Β βββ es
Β Β β βββ translation.json
Β Β βββ index.js
// App.js
import React from "react";
import /*translations from*/ "./locales";
// import { addTranslations } from "@fs/zion-locale";
import { useTranslation } from "react-i18next";
// addTranslations(translations);
export default function App() {
const [t] = useTranslation();
return (
<div>
<h1>{t("overview")}</h1>
</div>
);
}
{
"overview": "Overview"
}
// intentionally left blank
// App.js
import React from "react";
import translations from "./locales";
import { addTranslations } from "@fs/zion-locale";
import { useTranslation } from "react-i18next";
addTranslations(translations);
export default function App() {
const [t] = useTranslation();
return (
<div>
<h1>{t("overview")}</h1>
</div>
);
}
// https://edge.fscdn.org/assets/static/locales/en/translation-1h4l12412m.json
{
"overview": "Overview",
"ok": "OK",
"stuff": "Stuff",
}
.
βββ App.js
βββ node_modules
β βββ @fs
β βββ zion-locale
β βββ locales
β βββ de
β β βββ common-ui.json
β β βββ translation.json
β βββ en
β β βββ common-ui.json
β β βββ translation.json
β βββ es
β β βββ common-ui.json
β β βββ translation.json
β βββ index.js
βββ locales
βββ de
β βββ translation.json
βββ en
β βββ translation.json
βββ es
β βββ translation.json
βββ index.js
// intentionally left blank
// https://edge.fscdn.org/assets/static/locales/en/common-ui-123irnwelk.json
{
"common.things": "Common Things",
"cool": "Super cool"
}
module.exports = {}
// index.html
<script>
window.localeManifest = {
'en-translation': 'https://edge.fscdn.org/assets/static/locales/en/translation-1h4l12412m.json',
'en-common-ui': 'https://edge.fscdn.org/assets/static/locales/en/common-io-mmklk3i23.json',
}
</script>
<script src="https://edge.fscdn.org/assets/static/js/main-sdfisdg9e.js">
// @fs/zion-locale
import i18n from "i18next"
import Backend from "i18next-http-backend";
i18n
.use(Backend)
.init({
backend: {
loadPath: (locale, ns) => window.localeManifest?.[`${locale}-${ns}`]
}
});
Major bump to zion-locale
need to figure out a way to load locales in storybook
could be loading unused locale strings
our own implementation
Β
21% smaller
1284KB
1012KB
22% smaller
1240KB
967KB
11% smaller
1247KB
1106KB
npm i @fs/react-scripts@6.0.0-beta.6
npm i @fs/zion-locale@3.4.0-beta.0