fnando / i18n Goto Github PK
View Code? Open in Web Editor NEWA small library to provide the I18n translations on the JavaScript.
Home Page: https://fnando.github.io/i18n/
License: MIT License
A small library to provide the I18n translations on the JavaScript.
Home Page: https://fnando.github.io/i18n/
License: MIT License
I was having same issue as people in i18n-js issues like this one:
fnando/i18n-js#424
Maybe somebody will need solution for i18n library:
import library from ./src like that:
import { I18n, TranslateOptions } from 'i18n-js/src';
add defaultSeparator
const i18n: I18n = new I18n(translations, { defaultSeparator: '|' });
apply patch-package (https://github.com/ds300/patch-package)
here is it's code:
diff --git a/node_modules/i18n-js/src/I18n.ts b/node_modules/i18n-js/src/I18n.ts
index 43476f5..d53712e 100644
--- a/node_modules/i18n-js/src/I18n.ts
+++ b/node_modules/i18n-js/src/I18n.ts
@@ -255,11 +255,11 @@ export class I18n {
* @returns {void}
*/
public store(translations: Dict): void {
- const map = propertyFlatList(translations);
+ const map = propertyFlatList(translations, this.defaultSeparator);
- map.forEach((path) =>
- set(this.translations, path, get(translations, path)),
- );
+ map.forEach((path) => {
+ this.translations[path] = translations[path.split(this.defaultSeparator)[0]][path.split(this.defaultSeparator)[1]]
+ })
this.hasChanged();
}
diff --git a/node_modules/i18n-js/src/helpers/lookup.ts b/node_modules/i18n-js/src/helpers/lookup.ts
index 595d17c..b11dd27 100644
--- a/node_modules/i18n-js/src/helpers/lookup.ts
+++ b/node_modules/i18n-js/src/helpers/lookup.ts
@@ -36,9 +36,7 @@ export function lookup(i18n: I18n, scope: Scope, options: Dict = {}): any {
.map((component) => i18n.transformKey(component))
.join(".");
- const entries = locales.map((locale) =>
- get(i18n.translations, [locale, scope].join(".")),
- );
+ const entries = locales.map((locale) => i18n.translations[[locale, scope].join(i18n.defaultSeparator)]);
entries.push(options.defaultValue);
diff --git a/node_modules/i18n-js/src/helpers/propertyFlatList.ts b/node_modules/i18n-js/src/helpers/propertyFlatList.ts
index 5ebc9e2..d83ee90 100644
--- a/node_modules/i18n-js/src/helpers/propertyFlatList.ts
+++ b/node_modules/i18n-js/src/helpers/propertyFlatList.ts
@@ -10,9 +10,11 @@ interface Indexable {
class PropertyFlatList {
public target: Dict;
+ public defaultSeparator: string;
- constructor(target: Dict) {
+ constructor(target: Dict, defaultSeparator: string) {
this.target = target;
+ this.defaultSeparator = defaultSeparator;
}
call(): string[] {
@@ -30,8 +32,7 @@ class PropertyFlatList {
compute(value: unknown, path: string): unknown {
if (!isArray(value) && isObject(value)) {
return Object.keys(value).map((key) =>
- this.compute((value as Indexable)[key] as unknown, `${path}.${key}`),
- );
+ this.compute((value as Indexable)[key] as unknown, `${path}${this.defaultSeparator}${key}`));
} else {
return path;
}
@@ -70,6 +71,6 @@ class PropertyFlatList {
*
* @returns {string[]} The list of paths.
*/
-export function propertyFlatList(target: Dict): string[] {
- return new PropertyFlatList(target).call();
+export function propertyFlatList(target: Dict, defaultSeparator: string): string[] {
+ return new PropertyFlatList(target, defaultSeparator).call();
}
Let's say your app supports english and german language. User with czech locale logs in and the app fallbacks to english.
Currently, if you setup i18n like this:
export const i18n = new I18n(
enableHiddenFeatures
? translations
: {
en: translations.en,
de: translations.de,
}
)
i18n.locale = 'cs'
i18n.defaultLocale = 'en'
i18n.enableFallback = true
i18n.locale
returns "cs"
despite en translations being used.
Add function getUsedLocale()
that will return locale that is currently used by the library.
In my example above, we can test keys(translations).include(I18n.locale)
, but parsing language code is not that straight forward usually it might be in format like da_DK
or de_DE
. This logic is already included in the library and it does not seem right to duplicate it to find out what language is used.
After set locale, the component does not get re-rendered.
The component get re-rendered after changing locale.
Today the i18n object methods that accepts "Scope" as an argument are simply: type Scope = string | string[]
My solution is making the i18n class generic and the Scope
type will be depending on the translations object loaded to i18n.
I have considered making a redeclare in my project, the better solution will be making i18n generic and it will improve the developer experience.
I already made the changes locally and waiting for a permission to make a PR.
very similar key exist may return object but not string translation.
For Example I have below two key with translation
I get translation result below
properly render result with similar key like cardno cardno. or phoneno phoneno.
return{"": undefined, "0": "P", "1": "h", "2": "o", "3": "n", "4": "e", "5": " ", "6": "#"}
using "i18n-js": "4.3.2"
Hi, the newly released v4.3.0 vendored the whole lodash library to improve compatibility with importmap
However, this choice comes with some drawbacks, like:
I do not know a solution, I'm going to make some proposals:
isArray
(probably a breaking change that require a major release)I'm not a JavaScript developer, but I'm willing to help in finding an alternative
i18n.numberToPercentage(undefined)
Throws an error:
TypeError: Cannot read properties of undefined (reading 'toString') (webpack-internal:///./node_modules/i18n-js/dist/import/helpers/formatNumber.js:60)
The original code is here https://github.com/fnando/i18n/blob/main/src/helpers/formatNumber.ts#L89
if (originalNumber.isNaN()) {
formattedNumber = input.toString();
}
The function will return undefined if the input
is undefined
"i18n-js": "4.0.0-alpha.14"
I recently upgraded from v3.8 to v.4.1.1 but it seems that in this version we're not able to interpolate over an array, which was possible using v3.8, so I thinks it's a regression.
Just add to your translations a simple array like:
someTranslation: ["Some text", "Value of something is {{value}}"]
Then try to interpolate over it, like:
i18n.t('someTranslation', { value: 123 })
It should give the following result: ["Some text", "Value of something is 123"]
It doesn't throw any error, just returns: ["Some text", "Value of something is {{value}}"]
When using the library with importmap the following error is thrown:
The requested module 'lodash' does not provide an export named 'flattenDeep'
The offending code appears to be at the very top of /dist/import/index.js, in the first import statement:
import{uniq as e,camelCase as n,repeat as r,get as i,zipObject as s,sortBy as o,flattenDeep as a,isArray as l,isObject as c,range as u,set as h,has as d}from"lodash";
I'm able to reproduce the error in JSPM's sandbox using the following code:
<script type="importmap">
{
"imports": {
"i18n-js": "https://ga.jspm.io/npm:[email protected]/dist/import/index.js"
},
"scopes": {
"https://ga.jspm.io/": {
"bignumber.js": "https://ga.jspm.io/npm:[email protected]/bignumber.mjs",
"lodash": "https://ga.jspm.io/npm:[email protected]/lodash.js"
}
}
}
</script>
<script type="module">
import { i18nJs } from "i18n-js";
console.log(i18nJs);
</script>
I don't see anything wrong with the import statement, but then again exports/imports aren't really in my wheelhouse. Could the problem instead be with the way Lodash exports flattenDeep?
Thanks!
I have a React Native project that using i18n-js. But when I execute the building, I have the following error:
Error: While trying to resolve module
make-pluralfrom file
/node_modules/i18n-js/dist/import/Pluralization.js, the package
/node_modules/make-plural/package.jsonwas successfully found. However, this package itself specifies a
main module field that could not be resolved (
/node_modules/make-plural/plurals.mjs. Indeed, none of these files exist:
"React native": "0.67.5"
"i18n-js": "^4.2.3"
When I tried to load some translations with i18n-js, I have an error like this one :
My repository is a Solito monorepo and I want to use your library to translate the React Native part.
To reproduce this error :
[Describe what do you expect to happen]
I would like there to be no more errors when calling the get
method
TypeError: Cannot read property 'get' of undefined
This error is located at:
in Header (created by HomeScreen)
in RCTView (created by View)
in View
in NativeWind.View
in NativeWind.NoName
in Unknown (created by HomeScreen)
in HomeScreen (created by Home)
in Home
in Unknown (created by Route(index))
in Route (created by Route(index))
in Route(index) (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)
in SceneView (created by SceneView)
in RCTView (created by View)
in View (created by DebugContainer)
in DebugContainer (created by MaybeNestedStack)
in MaybeNestedStack (created by SceneView)
in RCTView (created by View)
in View (created by SceneView)
in RNSScreen
in Unknown (created by InnerScreen)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by InnerScreen)
in InnerScreen (created by Screen)
in Screen (created by SceneView)
in SceneView (created by NativeStackViewInner)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by ScreenStack)
in RNSScreenStack (created by ScreenStack)
in ScreenStack (created by NativeStackViewInner)
in NativeStackViewInner (created by NativeStackView)
in RCTView (created by View)
in View (created by SafeAreaInsetsContext)
in SafeAreaProviderCompat (created by NativeStackView)
in NativeStackView (created by NativeStackNavigator)
in PreventRemoveProvider (created by NavigationContent)
in NavigationContent
in Unknown (created by NativeStackNavigator)
in NativeStackNavigator
in Unknown (created by Root)
in RNCSafeAreaProvider (created by SafeAreaProvider)
in SafeAreaProvider (created by Provider)
in Provider (created by Root)
in Root
in Unknown (created by Route())
in Route (created by Route())
in Route() (created by ContextNavigator)
in RNCSafeAreaProvider (created by SafeAreaProvider)
in SafeAreaProvider (created by wrapper)
in RCTView (created by View)
in View (created by GestureHandlerRootView)
in GestureHandlerRootView (created by GestureHandlerRootView)
in GestureHandlerRootView (created by wrapper)
in wrapper (created by ContextNavigator)
in EnsureSingleNavigator
in BaseNavigationContainer
in ThemeProvider
in NavigationContainerInner (created by ContextNavigator)
in ContextNavigator (created by ExpoRoot)
in ExpoRoot (created by App)
in App (created by withDevTools(App))
in withDevTools(App) (created by ErrorOverlay)
in ErrorToastContainer (created by ErrorOverlay)
in ErrorOverlay
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in main(RootComponent), js engine: hermes
When using i18n-js with Create React App, webpack is not able to find src folder and cannot generate source map and I got warning in compilation.
import { I18n } from 'i18n-js'
const i18n = new I18n()
No warning should be appear in console
Warning about missing file is generated
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\I18n.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\I18n.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\Locales.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\Locales.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\MissingTranslation.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\MissingTranslation.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\Pluralization.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\Pluralization.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\camelCaseKeys.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\camelCaseKeys.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\createTranslationOptions.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\createTranslationOptions.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\expandRoundMode.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\expandRoundMode.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\formatNumber.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\formatNumber.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\getFullScope.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\getFullScope.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\index.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\index.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\inferType.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\inferType.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\interpolate.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\interpolate.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\isSet.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\isSet.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\lookup.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\lookup.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\numberToDelimited.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\numberToDelimited.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\numberToHuman.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\numberToHuman.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\numberToHumanSize.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\numberToHumanSize.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\parseDate.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\parseDate.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\pluralize.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\pluralize.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\propertyFlatList.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\propertyFlatList.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\roundNumber.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\roundNumber.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\strftime.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\strftime.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\timeAgoInWords.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\helpers\timeAgoInWords.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\index.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\index.ts'
Failed to parse source map from 'C:\Users\path-to-project\node_modules\i18n-js\src\typing.ts' file: Error: ENOENT: no such file or directory, open 'C:\Users\path-to-project\node_modules\i18n-js\src\typing.ts'
Hi! 👋
Firstly, thanks for your work on this project! 🙂
Today I used patch-package to patch [email protected]
for the project I'm working on.
I was trying to find a solution for the annoying warning I get everytime I run my React Native app:
**WARN** Require cycle: node_modules\i18n-js\dist\import\helpers\index.js -> node_modules\i18n-js\dist\import\helpers\formatNumber.js -> node_modules\i18n-js\dist\import\helpers\index.js
Require cycles are allowed, but can result in uninitialized values. Consider refactoalues. Consider refactoring to remove alues. Consider refactoring to remove the need for a cycle.
Here is the diff that solved my problem:
diff --git a/node_modules/i18n-js/dist/import/helpers/formatNumber.js b/node_modules/i18n-js/dist/import/helpers/formatNumber.js
index 5c39971..8856136 100644
--- a/node_modules/i18n-js/dist/import/helpers/formatNumber.js
+++ b/node_modules/i18n-js/dist/import/helpers/formatNumber.js
@@ -1,6 +1,7 @@
import BigNumber from "bignumber.js";
import { repeat } from "lodash";
-import { roundNumber } from ".";
+import { roundNumber } from "./roundNumber";
+
function replaceInFormat(format, { formattedNumber, unit }) {
return format.replace("%n", formattedNumber).replace("%u", unit);
}
This issue body was partially generated by patch-package.
Hi,
I simply want to perform translations without use of above two libraries. When I add this library using importmap on Rails 7 application, it also adds bignumber and lodash in my assets.
I still get error even when I added these two files in my assets.
I get error as "The requested module 'lodash' does not provide an export named 'flattenDeep'".
Is there any specific reason that these two libraries are automatically added when we add i18n library?
Can you help me out how I can get it fixed?
Thanks.
I'm currently looking for a way to use this package using React & Next.js but I get the following error Unexpected token 'export'
due to the fact I can only use commonjs package.
Regarding the structure of the project I can see 3 folders under the dist folder : import, browser & require. The main file registered in package.json is dist/import/index.js
.
So I found 2 way to fix this:
i18n-js/dist/require
but in Typescript I get the following error Could not find a declaration file for module i18n-js
dist/require/index.js
So I go into the second solution, for those facing the same issues you can find the package here: https://www.npmjs.com/package/@lagregance/i18n-js-require
Maybe I miss it, but since the relevant package is available inside the dist folder we should have a way to use it without making a fork (my idea is to publish alternative version like 4.2.2_require
).
Thanks for help.
Hey!
I`m trying to use i18n.numberToCurrency method and format some numbers to current local string but get error that roundNumber is undefined.
Having changed a path to the ./roundNumber I got rid of this error
i18n/src/helpers/formatNumber.ts
Line 5 in c446c84
I have attempted to install, configure and use i18n-js
via Importmaps (via Rails). Unfortunately, I get a ton of failing GET requests, where Lodash appears to look for the .js files using wrong paths.
$ ./bin/importmap pin [email protected] --download
pin "i18n-js" # @4.2.3
pin "bignumber.js" # @9.1.1
pin "lodash/camelCase", to: "lodash--camelCase.js" # @4.17.21
pin "lodash/flattenDeep", to: "lodash--flattenDeep.js" # @4.17.21
pin "lodash/get", to: "lodash--get.js" # @4.17.21
pin "lodash/has", to: "lodash--has.js" # @4.17.21
pin "lodash/isArray", to: "lodash--isArray.js" # @4.17.21
pin "lodash/isObject", to: "lodash--isObject.js" # @4.17.21
pin "lodash/range", to: "lodash--range.js" # @4.17.21
pin "lodash/repeat", to: "lodash--repeat.js" # @4.17.21
pin "lodash/set", to: "lodash--set.js" # @4.17.21
pin "lodash/sortBy", to: "lodash--sortBy.js" # @4.17.21
pin "lodash/uniq", to: "lodash--uniq.js" # @4.17.21
pin "lodash/zipObject", to: "lodash--zipObject.js" # @4.17.21
pin "make-plural" # @7.0.0
my_app/vendor/javascript/bignumber.js.js
my_app/vendor/javascript/i18n-js.js
my_app/vendor/javascript/lodash--camelCase.js
my_app/vendor/javascript/lodash--flattenDeep.js
my_app/vendor/javascript/lodash--get.js
my_app/vendor/javascript/lodash--has.js
my_app/vendor/javascript/lodash--isArray.js
my_app/vendor/javascript/lodash--isObject.js
my_app/vendor/javascript/lodash--range.js
my_app/vendor/javascript/lodash--repeat.js
my_app/vendor/javascript/lodash--set.js
my_app/vendor/javascript/lodash--sortBy.js
my_app/vendor/javascript/lodash--uniq.js
my_app/vendor/javascript/lodash--zipObject.js
my_app/vendor/javascript/make-plural.js
<script type="importmap" data-turbo-track="reload">{
"imports": {
...
"i18n-js": "/assets/i18n-js-04b620e607b4a8fc4d369deb77ddaca4c314ff3f5b113425aa02a5463c0f2a03.js",
"bignumber.js": "/assets/bignumber.js-da37e3c473288a78d1c8f160c092a279052ebe856db1dcafe6e3d6d1b5afa239.js",
"lodash/camelCase": "/assets/lodash--camelCase-6f67652d0026ec4ab6b1f27196f08a44304fa605aa6ff96fe6ec82fa285694d1.js",
"lodash/flattenDeep": "/assets/lodash--flattenDeep-2f4edb1bfdbc4fbfdb2e7eefd3d37d5e2e4b88dee8f10c06789ddbb360057939.js",
"lodash/get": "/assets/lodash--get-35a2d1636af7ea4edad2fda72147bffaa45bae5656450a0e43f0243ffddf7d6f.js",
"lodash/has": "/assets/lodash--has-64e2b530099782a9245954fc3d0686a0435d5a4e36731b4487e53afa61487b41.js",
"lodash/isArray": "/assets/lodash--isArray-90fbbd88ee79467a159561db8b16654aff7a93cedcdc52b7db2e16b0ae7afe87.js",
"lodash/isObject": "/assets/lodash--isObject-4fab301185da7b0352cb57ea604e3424e95ab46992c48137bbcfe8e7251da840.js",
"lodash/range": "/assets/lodash--range-c1e03f0ecbfd42e639fbd6729f8bc0b1ecef043c35ded308fcf0f9ae4360cb05.js",
"lodash/repeat": "/assets/lodash--repeat-5664123cae867b181825acae4eb06f468f07dc03e88e20baceddf91b1696282b.js",
"lodash/set": "/assets/lodash--set-82bc400373c55188224ac34f828c43950c4c575acca0d105024d85afe8b0f4e1.js",
"lodash/sortBy": "/assets/lodash--sortBy-b081313fe9cbc9c19866f545b40357fc4a58f822fab6b893a1603c5c7b757fd6.js",
"lodash/uniq": "/assets/lodash--uniq-b0fd5fd63d0fc1141fe47e7b2f16beefc916c1d87b07b43e69ee4813c105dac9.js",
"lodash/zipObject": "/assets/lodash--zipObject-db9bbd8ec0b6e7ebc0cde82b511a40ff8fb16457fe92b7532903f07b172c2db4.js",
"make-plural": "/assets/make-plural-2d052f6889f01180b0da040eb353fe7f921e763196a1003a289337fa09a8f10d.js",
...
}
}</script>
import { I18n } from "i18n-js";
console.log(I18n);
GET http://127.0.0.1:3000/assets/isArray.js
GET http://127.0.0.1:3000/assets/_/51cf0f3b.js
GET http://127.0.0.1:3000/assets/_/301ffe46.js
GET http://127.0.0.1:3000/assets/isObjectLike.js
GET http://127.0.0.1:3000/assets/isSymbol.js
GET http://127.0.0.1:3000/assets/_/bc38db9b.js
GET http://127.0.0.1:3000/assets/isObject.js
GET http://127.0.0.1:3000/assets/isFunction.js
GET http://127.0.0.1:3000/assets/_/e44fb5c7.js
GET http://127.0.0.1:3000/assets/_/27ce0419.js
GET http://127.0.0.1:3000/assets/_/da7e18fe.js
GET http://127.0.0.1:3000/assets/eq.js
GET http://127.0.0.1:3000/assets/_/6d2b6c8f.js
GET http://127.0.0.1:3000/assets/memoize.js
GET http://127.0.0.1:3000/assets/_stringToPath.js
GET http://127.0.0.1:3000/assets/_arrayMap.js
GET http://127.0.0.1:3000/assets/_/5bbd3627.js
GET http://127.0.0.1:3000/assets/toString.js
GET http://127.0.0.1:3000/assets/_toKey.js
GET http://127.0.0.1:3000/assets/isArguments.js
GET http://127.0.0.1:3000/assets/isLength.js
GET http://127.0.0.1:3000/assets/_/25787e84.js
GET http://127.0.0.1:3000/assets/_/db1f5abb.js
GET http://127.0.0.1:3000/assets/isArray.js
_.has
is the originhttp://127.0.0.1:3000/assets/lodash--has-64e2b530099782a9245954fc3d0686a0435d5a4e36731b4487e53afa61487b41.js
import"./isArray.js";
import"./isArray.js";import"./_/51cf0f3b.js";import"./_/301ffe46.js";import"./isObjectLike.js";import"./isSymbol.js";import"./_/bc38db9b.js";import"./isObject.js";import"./isFunction.js";import"./_/e44fb5c7.js";import"./_/27ce0419.js";import"./_/da7e18fe.js";import"./eq.js";import"./_/6d2b6c8f.js";import"./memoize.js";import"./_stringToPath.js";import"./_arrayMap.js";import"./_/5bbd3627.js";import"./toString.js";import"./_toKey.js";import"./isArguments.js";import"./isLength.js";import"./_/25787e84.js";import{_ as r}from"./_/db1f5abb.js";var t={};var s=Object.prototype;var i=s.hasOwnProperty;
//...
import { Dict, I18n, I18nOptions, Scope, TranslateOptions } from "i18n-js";
No error
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
C:\p\spring-docker\node_modules\i18n-js\dist\import\index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export { I18n } from "./I18n";
^^^^^^
SyntaxError: Unexpected token 'export'
"preset": "jest-expo",
[Paste full backtrace here]
At this point, the missingBehavior
is one of the i18n options that is set at the class instance creation
Line 216 in 60bb7f8
Having a few strategies of how to deal with a missing translation is great, but a lot of times we UI would benefit from a dynamic choice of what behavior to use for a particular UI place.
For example, if I have a enumerable set of translations for some predefined types: "cat", "dog", "rat".
en:
animals:
cat: Cat
dog: Dog
rat: Rat
and I have a UI
const getAnimalLabel = (type) =>
<span class="my-animal">{i18n.t(`animals.{type}`)}</span>
I want this function to return an empty span
if there is no translation. I don't want an error or a string like <span>"[missing "animals.bird" translation]"</span>
for this particular UI place. Currently, there is no easy way to deal with this simple case.
There is a small solution that unlocks this scenario, just updating a single line
i18n/src/MissingTranslation.ts
Line 152 in 60bb7f8
into
public get(scope: Scope, options: Dict): string {
return this.registry[options.missingBehavior || this.i18n.missingBehavior](this.i18n, scope, options);
}
in this case, I could register my custom strategy:
const emptyStrategy = () => undefined
class PatchedMissingTranslation extends MissingTranslation {
constructor(...args) {
super(...args)
this.register('empty', emptyStrategy)
}
}
And use it in my code:
const getAnimalLabel = (type) =>
<span class="my-animal">{i18n.t(`animals.{type}`, {missingBehavior: 'empty'})}</span>
The alternative is to override the get
method in the user code. This works but maybe a problem in the long run if the i18n would change the MissingTranslation
implementation
Also, it would be great to include a suggested empty
strategy into the list of default strategies
i18n/src/MissingTranslation.ts
Lines 109 to 111 in 60bb7f8
After upgrading to the latest version, i got a lot of typescript errors.
TS2551: Property 'locale' does not exist on type 'typeof import("/node_modules/i18n-js/typings/index")'. Did you mean 'Locales'?
TS2339: Property 't' does not exist on type 'typeof import("/node_modules/i18n-js/typings/index")'.
I've tried to remove @types/i18n-js, but nothing has changed.
i18n allows us to return a translation for a scope as an array or an object, but i18n.t
has only string
as return type, causing TypeErrors if you try to use it as something that isn't a string.
Just try to use a directly return from i18n.t as string[]
or some object type.
i18n.t
should have more than just string as return type.
TypeError, because i18n.t
always return a string, according to its type.
i18n/src/helpers/interpolate.ts
Lines 47 to 49 in 27e14e7
Incorrect Regular Expression Severity: Medium
RegExp() called with a variable, this might allow an attacker to DOS your application with a long-running regular expression.
When upgrading I18n-js to 4.4.0+ we have an error : I18n is not a constructor
You can reproduce with following sandbox, downgrading to 3.2.0 will make the page work.
https://codesandbox.io/p/sandbox/upbeat-lamarr-hpz9qp?file=%2Fpackage.json%3A14%2C31
Page should load without error.
renderWithHooks
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:16305:18
mountIndeterminateComponent
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:20074:13
beginWork
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:21587:16
HTMLUnknownElement.callCallback
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:4164:14
Object.invokeGuardedCallbackDev
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:4213:16
invokeGuardedCallback
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:4277:31
beginWork$1
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:27451:7
performUnitOfWork
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:26557:12
workLoopSync
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:26466:5
renderRootSync
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:26434:7
performConcurrentWorkOnRoot
https://hpz9qp.csb.app/node_modules/react-dom/cjs/react-dom.development.js:25738:74
workLoop
https://hpz9qp.csb.app/node_modules/scheduler/cjs/scheduler.development.js:266:34
flushWork
https://hpz9qp.csb.app/node_modules/scheduler/cjs/scheduler.development.js:239:14
MessagePort.performWorkUntilDeadline
https://hpz9qp.csb.app/node_modules/scheduler/cjs/scheduler.development.js:533:21
The return type is any
rather than string
which is documented
Missing export in browser/index.js
import { I18n } from 'i18n-js';
Import the I18n
.
It's returning void.
18:54:16 js.1 | ▲ [WARNING] Import "I18n" will always be undefined because the file "../../node_modules/i18n-js/dist/browser/index.js" has no exports [import-is-undefined]
18:54:16 js.1 |
18:54:16 js.1 | modules/i18n.js:1:9:
18:54:16 js.1 | 1 │ import { I18n } from 'i18n-js';
As in the title, it is not possible to omit options
argument of formatNumber
.
There is an example in the readme indicating it should work:
i18n.t("points", {
count: points,
points: i18n.formatNumber(points),
});
However, this actually leads to following error:
formatNumber.js:17 Uncaught TypeError: Cannot read properties of undefined (reading 'raise')
at formatNumber (formatNumber.js:17:1)
at I18n.formatNumber (I18n.js:274:28)
Passing empty object as options results in NaN
being returned.
As in the example, and similar to how to Intl
allows, I would expect that it's possible to omit the options
param:
Intl.NumberFormat().format(14.45435)
Hi,
you mention to build a custom interpolate function, do you have any example on how it would look like to do this:
const i18n = new I18n({
en: { greetings: "Hi, %{name}!" },
"pt-BR": { greetings: "Olá, %{name}!" },
});
i18n.interpolate = (i18n, message, options) => {
// ...
};
return <Text>{i18n.t("greetings", { name: <BoldText>John</BoldText> })}</Text>;
Thanks
Right now we're reimplementing pluralization rules, so there's only 3 mechanisms supported. To have a better reach, let's migrate to https://www.npmjs.com/package/make-plural
We need to make sure that existing tests keep passing without changes. The pluralization activation should be automatic without requiring configuration.
If i18n.translate(scope)
does not target a leaf node the return is an object. This generally is useless in the UI, in this case, it would be better to return a standard missing translation string.
const i18n = new I18n({en: {labels: {a: "A"}}})
console.log(i18n.translate('labels'))
Output:
[object Object]
Ideally, it should be claimed as missing translation and processed via a missing translation strategy. So for a default case of using message
strategy, it would be expected to get a string:
[missing "en.labels" translation]
An object was returned, despite the original intent of always returning a string from translate
method. As per the source code
Line 379 in 60bb7f8
"i18n-js": "4.0.0-alpha.14"
Importing asimport { I18n } from 'i18n-js';
throws TS error 'I18n' can only be imported by using a default import
. Importing as default import import I18n from 'i18n-js';
throws on new I18n()
This expression is not constructable. Type 'typeof I18n' has no construct signatures.
Use I18n as described in docs
Not to throws Typescript error
[https://github.com/fnando/i18n/tree/main#missing-translations] lists several ways to register fallback languages but that doesn't work.
// Using an array
i18n.locales.register("no", ["nb", "en"]);
// Using a string
i18n.locales.no.register("nb");
// Using a function.
i18n.locales.no.register((locale) => ["nb"]);
Only the first variant works, i18n.locales.${localename}.register doesn't work.
Also when I tried to use the first variant i18n.locales.register("de", ["en"]);
to set "en" as fallback for "de", then it failed with i18n.t("existingkey")
even though i18n.translations.de.existingkey
existed and i18n.locale
was set to de
.
I18n.locales.de.register("en");
Missing behavior to be registered
- error TypeError: Cannot read properties of undefined (reading 'register')
Package seems to not work with Next.js anymore.
npx create-next-app i18n-test --ts
npm i i18n-js@latest
Create data.json
in root folder.
{
"Hello" : "Guten morgen"
}
Create i18n.ts in root folder.
import { I18n } from "i18n-js";
import data from './data.json'
export const i18n = new I18n({
...data
})
Use translation in any page to reproduce the bug.
node: 16.13.2
next: 13.2.3
react: 18.2.0
error - /Users/michal/Documents/projects/i18n-test/node_modules/i18n-js/dist/import/index.js:1
export { I18n } from "./I18n";
^^^^^^
SyntaxError: Unexpected token 'export'
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1031:15)
at Module._compile (node:internal/modules/cjs/loader:1065:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.i18n-js (/Users/michal/Documents/projects/i18n-test/.next/server/pages/index.js:54:18)
at __webpack_require__ (/Users/michal/Documents/projects/i18n-test/.next/server/webpack-runtime.js:33:42)
at eval (webpack-internal:///./i18n.ts:5:65)
at Object../i18n.ts (/Users/michal/Documents/projects/i18n-test/.next/server/pages/index.js:32:1)
at __webpack_require__ (/Users/michal/Documents/projects/i18n-test/.next/server/webpack-runtime.js:33:42)
at eval (webpack-internal:///./pages/index.tsx:9:63)
at Object../pages/index.tsx (/Users/michal/Documents/projects/i18n-test/.next/server/pages/index.js:43:1)
at __webpack_require__ (/Users/michal/Documents/projects/i18n-test/.next/server/webpack-runtime.js:33:42)
at __webpack_exec__ (/Users/michal/Documents/projects/i18n-test/.next/server/pages/index.js:97:39)
at /Users/michal/Documents/projects/i18n-test/.next/server/pages/index.js:98:28
at Object.<anonymous> (/Users/michal/Documents/projects/i18n-test/.next/server/pages/index.js:101:3)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.requirePage (/Users/michal/Documents/projects/i18n-test/node_modules/next/dist/server/require.js:88:12)
at /Users/michal/Documents/projects/i18n-test/node_modules/next/dist/server/load-components.js:49:73
at async Object.loadComponentsImpl [as loadComponents] (/Users/michal/Documents/projects/i18n-test/node_modules/next/dist/server/load-components.js:49:26)
at async DevServer.findPageComponentsImpl (/Users/michal/Documents/projects/i18n-test/node_modules/next/dist/server/next-server.js:599:36) {
page: '/'
}
If precision
option is not passed to numberToPercentage
it will return 'NaN%'
regardless of input
> I18n.numberToPercentage(55.55)
'NaN%'
> I18n.numberToPercentage(55.55, {precision: 0})
'56%'
I'd expect a default precision to kick in and return a numeric string value. The same applies to localize
calls, now it is
> I18n.l("percentage", 123.45)
'NaN%'
"i18n-js": "4.0.0-alpha.14",
The instructions for using webpack
with i18n
at https://github.com/fnando/i18n?tab=readme-ov-file#im-using-webpack-and-bundling-doesnt-work are likely outdated and should be reviewed/removed.
These instructions were introduced due to issues with the exports
field in version 4.4.1 of i18n
. However, it seems these modifications caused further problems with webpack
and esbuild
. Additionally, changing the default resolve.conditionNames
as advised might have unintended consequences for other libraries in large applications.
I had a problem with the 4.3.0 that I wanted to share.
My Nuxt 3 production build failed because of relative dependencies added in the generated js.
It took me a while to realize it came from the i18n package.
The relatives path added in the nuxt generated js concerned your '/src/vendor/lodash' directory
Anyway, browsing in your repo I see that these directory has been remove in 4.3.1-beta. So I upgrade and it's ok now.
In a react-native expo iOS app, after upgrading i18n-js to version 4+ (tested with 4.4.3, 4.4.2, and 4.0.0), I get a "Cannot read property 'prototype' of undefined" error when I try to instantiate a new I18n class.
This error has been reported here but I could only fix it by downgrading to version 3.8.0
Here's the code that triggers this issue:
import * as Localization from 'expo-localization';
import I18n from 'i18n-js';
import { en, fr, ru, ua, ca, de, it, sv, pl } from './languages';
const i18n = new I18n({ en, fr, ru, ua, ca, de, it, sv, pl });
i18n.fallbacks = true;
i18n.defaultLocale = 'en';
i18n.locale = Localization.locale;
export {i18n};
const i18n instantiated properly
"Cannot read property 'prototype' of undefined error"
Here's a screenshot of the stacktrace:
My app's main language is English, but it needs to support a few others, e.g.: Arabic. Arabic does not have the same pluralization rules as English, so I had to add a custom code to use "zero", "one", "two", etc. Unfortunately there are some missing translations in the app, where I need to fall back to English. However, when the pluralization key is not present, it crashes instead of giving the usual error message.
import { I18n } from "i18n-js";
const i18n = new I18n({
"ar": {
"weeks": {
"one": "1 week ago",
"other": "%{count} weeks ago"
}
}
});
i18n.pluralization.register('ar', (_i18n, count) => {
// Based on https://github.com/ruby-i18n/i18n/blob/master/test/test_data/locales/plurals.rb
if (count === 0) {
return ['zero'];
}
if (count === 1) {
return ['one'];
}
if (count === 2) {
return ['two'];
}
if ([3, 4, 5, 6, 7, 8, 9, 10].includes(count % 100)) {
return ['few'];
}
if (Number.isInteger(count)) {
return ['many'];
}
return ['other'];
});
i18n.locale = 'ar';
console.log(i18n.t("not_existing", { count: 1 })); // -> [missing "ar.not_existing" translation]
console.log(i18n.t("weeks", { count: 1 })); // -> 1 week ago
console.log(i18n.t("weeks", { count: 2 })); // -> Uncaught TypeError: message is undefined
It would be nice to get the same fallback as I have for missing keys (e.g.: [missing "ar.weeks.two" translation]
)
It raises an error and the whole page crashes.
[email protected]
Uncaught TypeError: message is undefined
interpolate ./node_modules/i18n-js/dist/import/helpers/interpolate.js:7
pluralize ./node_modules/i18n-js/dist/import/helpers/pluralize.js:26
pluralize ./node_modules/i18n-js/dist/import/I18n.js:118
translate ./node_modules/i18n-js/dist/import/I18n.js:87
<anonymous> ./src/index.js:43
If my understanding is correct, if you want to use different than default pluralizer you need to register when initializing i18n-js. This is different to rails-i18n where pluralizers are loaded based on locale.
Implement similar mechanism where the locale files included in this lib would optionally refference pluralizer name used for given locale.
If this is in deed a good idea I will prepare a PR.
I have a pretty simple typescript project that runs on Docker. I tried to upgrade from 3.9.2 to 4.2.2, but have been running into issues building the project with the error Unexpected token 'export'
. The error seems to be coming from the exports in the dist/index.js
file.
webpack
has been removed from development dependencies, but it is still used in build:browser
script
Line 40 in f20ebdb
Incoming reproducible test case
https://github.com/diowa/icare/actions/runs/7872274448/job/21477141544?pr=1650#step:10:43
Relevant change: https://github.com/diowa/icare/pull/1650/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519R32
Note
Sorry about the not-so-reduced test case. There are two JS errors, the second (google maps key) is unrelated. We are interested in the first one for this issue
ERROR
i18n_js__WEBPACK_IMPORTED_MODULE_0__.I18n is not a constructor
TypeError: i18n_js__WEBPACK_IMPORTED_MODULE_0__.I18n is not a constructor
import { I18n } from 'i18n-js'
import translations from 'src/locales/translations.json'
const i18n = new I18n(translations)
Since this is a minor release, I was expected the same behaviour as before. Or at least an entry in the changelog and updated documentation
Breaks JavaScript functionality
1) Application protects pages from guest users
Failure/Error: raise error_messages if severe_errors.any?
RuntimeError:
There were 2 JavaScript errors:
http://127.0.0.1:54260/packs-test/js/application.js 217:13 Uncaught TypeError: i18n_js__WEBPACK_IMPORTED_MODULE_0__.I18n is not a constructor
[Add bug description here]
[Add steps on how to reproduce this issue]
[Describe what do you expect to happen]
[Describe the actual results]
[Paste full backtrace here]
Numbers passed to pluralize
via count
are not delimited. For example, in en-US
:
1234 results
…should be:
1,234 results
A possible solution is to pass an optional displayCount
string that overrides the numeric count
in the output. For example:
const resultsCount = 1234;
i18n.t("results", {
count: resultsCount,
displayCount: i18n.numberToDelimited(resultsCount),
});
This would give more control over how the output is formatted. For example, if someone wanted to use numberToHuman
instead of numberToDelimited
.
There’s no alternative to this as far as I can tell, given how count
is parsed when a string is pluralized via zero
, one
, few
, many
, and other
. Happy to be proven wrong. 🙂
This is how pluralization works for FBT via PluralOptions.value
.
Thanks for all your work on this library!
In v3 of this library there was a .toNumber
method that appears to have been replaced by a formatNumber
helper in v4, however, that helper is not exported. Is there a reason for not exporting it? Additionally, the old method is still being mentioned in one place in the README which is wrong.
i18n.toNumber()
i18n.toNumber()
does not throw an error, or is replaced by i18n.formatNumber
which is publicly accessible and uses the formatNumber
helper
i18n.toNumber()
throws an error
TypeError: undefined is not a function
The I18n works but not in my Jest tests where it fails with the following error:
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
/Users/igortsykalo/workspace/covalent-ojt/node_modules/i18n-js/dist/import/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { I18n } from "./I18n";
^^^^^^
SyntaxError: Unexpected token 'export'
> 1 | import { I18n } from 'i18n-js';
| ^
2 | import en from './locales/en.json';
3 | import es from './locales/es.json';
4 |
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1796:14)
at Object.<anonymous> (app/javascript/i18n.js:1:1)
I've tried to follow Jest recommendations and added following to my jest.config.js
:
transform: {
'^.+\\.(js|jsx)$': 'babel-jest',
},
transformIgnorePatterns: ['<rootDir>/node_modules/(?!(i18n-js)/)'],
But this still did not help. I am using many other node_modules (react, material-ui, axios, etc.), but this is the first one that caused me issues.
Use i18n-js
with jest
works
fails
[Paste full backtrace here]
We use i18n-js with translations for units and we request the translations of the entire set of units. This used to work in previous versions but after switching to version 4 this results in a incomplete array. When we remove '1' key the problem is solved.
Thank you for your great work on this package!
import { I18n } from 'i18n-js'
export const i18n = new I18n()
i18n.store({ 'en': { 'units': { 'l': 'liter', '1': 'number' } } })
console.log(i18n.t('units'))
console.log(i18n.t('units.1'))
console.log(i18n.t('units.l'))
Expected this console output:
Object { l: "liter", 1: "number" }
number
liter
This is also what version 3.9.2 of i18n-js returned (using a similar setup).
This console output:
Array [ <1 empty slot>, "number" ]
number
liter
I have a React Native project that was using i18n-js.
This is the code:
import {I18n} from 'i18n-js';
import en from './en-US';
import pt from './pt-BR';
const translations = {en, 'pt-BR': pt};
type TranslationsTypes = keyof typeof translations;
const i18n = new I18n(translations);
export default i18n;
export const translate = (key: string) => i18n.t(key);
And this is a sample how I use:
import {translate} from 'i18n/src/locale';
<Text style={{color: '#DDDDDD', marginLeft: 5}}>
{translate('text_1')}
</Text>
But when I start my React Native project, I get this warning:
Require cycle: node_modules/i18n-js/dist/import/helpers/index.js -> node_modules/i18n-js/dist/import/helpers/formatNumber.js -> node_modules/i18n-js/dist/import/helpers/index.js
Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle.
Is this a i18n-js package problem, or did I something wrong?
Thanks
Using the i18n-js library in a React Native Expo application along with Expo-Localization.
Translations JSON object includes 2 languages: English and Spanish. As of a few days ago, my i18n.t("key") function is returning "Cannot convert object to primitive value" error. This was not the case as of about a week ago so I suspect it might relate to a recent change.
One note - I am using the JSON object to organize my translations into sub-objects
UPDATE - this only occurs when translating the label of a React Native button. Will investigate further.
translations: {
'en': {
screen_1: {
header: "Screen 1 header",
text: "Screen 1 text"
},
screen_2: {
header: "Screen 2 header",
text: "Screen 2 text"
}
},
'es': {
screen_1: {
header: "Encabezado de la pantalla 1",
text: "Texto de la pantalla 1"
},
screen_2: {
header: "Encabezado de la pantalla 2",
text: "Texto de la pantalla 2"
}
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.