Nur eine Frage:
Warum gibt es keine "en", "en-US" Gebietsschemas?
Ich verstehe, dass sie als Standardwert verwendet wurden. Wenn Sie dies wünschen, müssen Sie zunächst kein Gebietsschema verwenden.
Stellen Sie sich jedoch vor, Sie haben die typische Kombination, bei der der Benutzer das Gebietsschema auswählen kann.
Und Sie rufen moment.locale () mit dem aktuellen Wert auf.
In der aktuellen Situation muss man den Fall en / en-US als Sonderfall behandeln, was mir etwas umständlich erscheint.
Vielen Dank für Ihre großartige Arbeit. Drücke weiter!
Es gibt ein Gebietsschema en
, das nur nicht in einer separaten Datei enthalten ist. Es wird von moment().locale()
und moment.locale()
sehr akzeptiert:
moment.locale('fr')
"fr"
moment().format("LLLL")
"vendredi 25 novembre 2016 03:39"
moment.locale('en')
"en"
moment().format("LLLL")
"Friday, November 25, 2016 3:39 AM"
en-US
funktioniert auch, weil wir nach einer weniger spezifischen Übereinstimmung suchen und das Gebietsschema en
US-Englisch ist:
moment.locale('en-GB')
"en-gb"
moment().format("LLLL")
"Friday, 25 November 2016 03:40"
moment.locale('en-US')
"en"
moment().format("LLLL")
"Friday, November 25, 2016 3:40 AM"
Ich kaufe es nicht; Betrachten Sie den Fall, in dem das Gebietsschema von der Umgebung erkannt wird und dann ein erforderlicher Dep-Pfad erstellt wird, um moment / locale / $ {detectLocale} zu laden. Wenn diese Variable "en" oder "en-us" ist, kann requirejs keine Datei laden (erhält eine 404). Wenn es als ‚de‘ erkannt wird, dann wird die Datei laden.
Der Locale Loader von @eigood Moment weiß, dass er bereits Englisch spricht, und versucht nicht, es aus einer externen Datei zu laden.
@icambron Ich glaube nicht, dass Sie richtig sind, wenn Sie den Baum hinuntergehen, wenn der Benutzer "en-US" als Gebietsschema eingibt. Tatsächlich debugge ich gerade und es bricht, weil Sie NICHT den Baum hinuntergehen.
Mein Anwendungsfall ist, dass ich moment.utc (myDate, myFormat, locale, true) aufrufe, wobei locale nur eine einzelne Zeichenfolge 'en-US' ist. Da diese Zeichenfolge nicht importiert werden kann (da keine Datei dafür vorhanden ist), es sich jedoch nicht um ein Array handelt, wird versucht, das Gebietsschema zu benötigen, und es werden dann Produktionsumgebungen unterbrochen.
Es scheint mir, dass das wirklich beste Verhalten darin besteht, en-US tatsächlich in die Liste der standardmäßig vorhandenen Gebietsschemas aufzunehmen (es ist momentan nicht vorhanden, nur en allein).
@steveccable Nun, es wird versucht, es zu laden, nur für den Fall, dass Sie eine spezifischere Lokalisierung hatten. Wenn es fehlschlägt, versucht es nur "en" und ist erfolgreich. Ich denke, die Trennung ist nur, dass es irgendwie für Sie kaputt geht, wenn Sie "en-US" nicht laden. Hier soll nichts explodieren; Es soll nur anmutig scheitern und zur nächsten Option übergehen. Sie müssen mir also mehr über Ihre Umgebung erzählen: Was läuft konkret falsch?
@icambron Meine Umgebung ist eine React Native-Anwendung, die npm verwendet, um meine Abhängigkeiten zu steuern, und ich konnte den Fehler auch in minimalen Beispielanwendungen replizieren. Das Problem ist, dass in der Funktion loadLocale versucht wird, ('./ locale /' + name) anzufordern, wobei name en-US ist, und dass dies fehlschlägt. Wenn diese Anforderung in einem Release-Build fehlschlägt, stürzt die App mit einem Stack-Trace ab, wie folgt:
E/ReactNativeJS: Requiring unknown module "./locale/en-us".
E/AndroidRuntime: FATAL EXCEPTION: mqt_native_modules
Process: com.myApp, PID: 30054
com.facebook.react.common.JavascriptException: Requiring unknown module "./locale/en-US"., stack:
o<strong i="7">@2</strong>:742
n<strong i="8">@2</strong>:426
i<strong i="9">@2</strong>:278
t<strong i="10">@2</strong>:210
Xe<strong i="11">@648</strong>:16702
nt<strong i="12">@648</strong>:17804
gt<strong i="13">@648</strong>:22583
yt<strong i="14">@648</strong>:22460
wt<strong i="15">@648</strong>:23200
c<strong i="16">@648</strong>:1112
parse<strong i="17">@645</strong>:1536
render<strong i="18">@643</strong>:2923
_renderValidatedComponentWithoutOwnerOrContext<strong i="19">@141</strong>:7295
_renderValidatedComponent<strong i="20">@141</strong>:7462
performInitialMount<strong i="21">@141</strong>:3012
mountComponent<strong i="22">@141</strong>:2056
mountComponent<strong i="23">@132</strong>:205
performInitialMount<strong i="24">@141</strong>:3162
mountComponent<strong i="25">@141</strong>:2056
mountComponent<strong i="26">@132</strong>:205
performInitialMount<strong i="27">@141</strong>:3162
mountComponent<strong i="28">@141</strong>:2056
mountComponent<strong i="29">@132</strong>:205
Wenn getLocale den Code durchblättert und feststellt, dass mein Schlüssel ('en-US') kein Array ist, fällt er in loadLocale, ohne jemals zu versuchen, mit 'en' übereinzustimmen, was nur passieren würde, wenn er in die Funktion selectLocale gehen würde.
BEARBEITEN: Nachdem Sie sich die Funktion "ChooseLocale" etwas genauer angesehen haben, wird immer noch versucht, "en-US" zu wählen und dann die Anforderung zu verfehlen, bevor Sie jemals "en" versuchen wenn dies ein Array wäre.
Seltsam ist auch die Tatsache, dass sich die Stelle, an der es bricht, in einem Versuch / Fang befindet und dennoch einen Absturz verursacht. Das ist eigentlich die wirklich verwirrende Sache hier.
BEARBEITEN 2: Beachten Sie, dass die Anforderung in einem Debug-Build (__DEV__) ordnungsgemäß fehlschlägt und dann auf die Verwendung von 'en' zurückzuführen ist. Ich bin mir nicht sicher, warum erfordern in __PROD__ so viel explosiver ist, aber es bricht hier definitiv im Moment.
BEARBEITEN 3: In den erforderlichen js-Dokumenten heißt es: "Wenn Sie die Abhängigkeiten nicht ausdrücken, werden wahrscheinlich Ladefehler angezeigt, da RequireJS Skripte asynchron und aus Geschwindigkeitsgründen nicht in der richtigen Reihenfolge lädt." Daher ist es unwahrscheinlich, dass der Versuch / Fang uns hier tatsächlich rettet, da Versuch / Fang nur bei synchronen Fehlern wirklich hilft.
Nachdem ich es ein wenig durchgearbeitet habe, habe ich eine (weniger als ideale) Problemumgehung. Wenn mein Code versucht, ein Gebietsschema von 'en-US' zu übergeben, fange ich ihn ab und übergebe stattdessen ein Gebietsschema von 'en'. Andere Gebietsschemas dürfen unverändert durchlaufen werden.
Trotzdem halte ich es immer noch für problematisch, dass es weder en-US finden kann noch standardmäßig bereits vorhanden ist, und Sie können es nicht wie bei anderen Gebietsschemas spezifisch einschließen, um zu vermeiden, dass es nicht gefunden wird, wenn es tatsächlich aufgerufen wird auf.
@steveccable
Seltsam ist auch die Tatsache, dass sich die Stelle, an der es bricht, in einem Versuch / Fang befindet und dennoch einen Absturz verursacht. Das ist eigentlich die wirklich verwirrende Sache hier.
Richtig, das sage ich. Ich versuche zu verstehen, warum ein fehlgeschlagener Anruf katastrophal wäre. Ich würde nicht helfen, in Kenntnis von en-US
zu codieren; In jedem anderen Fallback-Fall hätten wir immer noch einen ähnlichen Fehler. Das hat also nichts damit zu tun, dass en
ein Sonderfall ist, sondern damit, dass der Fallback-Prozess in Ihrer Umgebung überhaupt nicht funktioniert.
Wenn Sie es durcharbeiten, scheint es, dass React Native nicht so fehlerhaft behandelt werden kann, wie wir es möchten. Sie haben Recht, dass es nichts damit zu tun hat, dass es sich um einen Sonderfall handelt, und der einzige Grund, warum es so schien, als wäre es ein Sonderfall, war, dass es keine Möglichkeit gab, das Scheitern der en-US-Anforderung zu verhindern (da wir es nicht direkt importieren können wie bei anderen Gebietsschemas). Wie in der späteren Bearbeitung erwähnt, funktioniert try / catch nicht, da es asynchron fehlschlägt.
Im Moment funktioniert die oben erwähnte Problemumgehung, nur Gebietsschemas von "en-US" zu bereinigen, für meine Zwecke.
Der Versuch / Fang funktioniert nicht, da er asynchron fehlschlägt
Oh, ich habe diese Bearbeitung verpasst. Das würde auch meine Vermutung sein.
@steveccable
Ich bin mir nicht sicher, ob Sie das Problem noch haben, aber genau die gleichen Abstürze beim Release-Build (obwohl mit dem französischen Gebietsschema) haben einen Arbeitstag für mich in Anspruch genommen 😢
E/ReactNativeJS: Requiring unknown module "./locale/fr".
(...)
Ich habe es gelöst mit:
import 'moment/locale/fr';
Vielleicht hilft es
Die Problemumgehung für die Bereinigung der Gebietsschemaeingabe ist in Ordnung, aber es ist wirklich beängstigend zu wissen, dass ein reaktionsfähiges natives require () an jedem Ort asynchron fehlschlagen kann und es keine Möglichkeit gibt, dies zu erfassen. Wenn ich ein nicht vorhandenes Gebietsschema oder eine zufällige Zeichenfolge (z. B. 'blah-Blah') sende, bedeutet dies, dass die App abstürzt und ich den Fehler nirgendwo behandeln kann. Also muss ich defensiv nachsehen, dass niemand diesen Fehler auslöst.
Nach Version 2.19.2 sind Probleme aufgetreten. Hier ist, was sich mit dieser Version geändert hat: https://github.com/moment/moment/compare/29afed6...328d51e Die Funktion updateLocale hat begonnen, loadLocale intern zu verwenden, was wiederum die Verwendung einer dynamischen Zeichenfolge https erfordert
Ich denke, dies schlägt bei der Reaktion auf native fehl, da Sie keine Dateien dynamisch über die Variable https://github.com/facebook/react-native/issues/6391 benötigen können
In meinem speziellen Fall importiere ich die en-gb-Datei, sodass sie zum Zeitpunkt des Aufrufs von moment.locale in locales[name]
werden sollte. Ich bin mir nicht sicher, warum es durchfällt, um zu verlangen.
Ich bin mir nicht sicher, ob RN Priorität hat oder nicht, aber der Moment für RN wird für Monate unterbrochen.
Bei alledem scheint Facebook # 69 die produktivste Lösung zu sein, um alle zu entsperren. Ich werde mit @jeanlauliac sprechen und sehen, ob wir es am Montag zusammenführen können.
Nur um einige Hintergrundinformationen zu geben: Es gibt mehrere Gründe, warum wir dynamische Abhängigkeiten nicht unterstützen. Erstens bricht die statische Analyse ab, wenn Module dynamisch benötigt werden. Zweitens ist bei Verwendung dynamischer Anforderungen möglicherweise das von Ihnen gesuchte reale Modul nicht verfügbar. Dies kann zu schwerwiegenden Problemen in der Produktion führen, die Benutzer daran hindern würden, unsere Apps zu verwenden, z. B. könnten wir Facebook beschädigen. Wir hatten in der Vergangenheit solche Probleme und es macht keinen Spaß, damit umzugehen. Metro hat absichtlich eine Meinung, um zu verhindern, dass Menschen Dinge tun, die den Benutzern Schmerzen bereiten.
Schließlich verstehen wir, dass dieses Open-Source-Repo derzeit nicht in einem hervorragenden Zustand ist. Die gute Nachricht ist, dass noch nie mehr Leute bei FB an Metro gearbeitet haben, und wir haben eine Reihe wichtiger Änderungen vor uns, um Metro um eine Tonne besser zu machen, aber die schlechte Nachricht ist, dass es dringende Probleme gibt, die wir lösen müssen zu Open Source. Wir hoffen, dass dieses Repo in ein paar Monaten in einem viel besseren Zustand sein wird und dass es einfacher sein wird, dazu beizutragen. Geben Sie uns bitte etwas Zeit.
Für RN habe ich es im Release-Modus zum Laufen gebracht, indem ich zum ersten Teil des Gebietsschemas gewechselt habe (wahrscheinlich, was hinter den Bildschirmen passiert, wenn das Gebietsschema "xx-XX" nicht geladen werden kann). Im folgenden Snippet ist locale
das Gebietsschema Ihres Geräts in der Form "xx-XX".
moment.locale(locale.indexOf("-") === -1 ? locale : locale.substr(0, locale.indexOf('-')))
Das ist komisches Verhalten.
https://stackoverflow.com/a/47260841/175825 Sie müssen ein bestimmtes Gebietsschema importieren, damit das Ökosystem sie nutzen kann.
Aufgrund dieser Magie kann ich keinen reaktionsgroßen Kalender dazu bringen, Daten wie mm/yy
mit BigCalendar.momentLocalizer()
anzuzeigen, da erwartet wird, dass das Gebietsschema geladen wird.
Ich könnte ein Problem mit dem React-Big-Kalender eröffnen, aber was ist mit der nächsten Bibliothek, auf die ich stoße und die ein bestimmtes Gebietsschema erwartet? Und der nächste?
Fügen Sie einfach das Gebietsschema en-us
und verwenden Sie standardmäßig Magie.
Fügen Sie einfach das Gebietsschema en-us hinzu und verwenden Sie standardmäßig Magie.
Es wird das Problem nicht lösen, es gibt Sprachen wie Spanisch ( es-ES
=> es
), die automatisch zurückgreifen.
Für alle, die noch nach einer Lösung suchen, kann dies helfen, das Problem zu beheben (mit Ausnahme einiger Randfälle), aber das Grundproblem von RN, das beim Absturz require
einen Absturz verursacht, wird nicht behoben:
import moment from 'moment/min/moment-with-locales.min.js';
// locale is the locale detected by react-native-device-info
// ts is the time
export const formatTime = (locale, ts) => {
const m = moment.utc(ts);
locale = chooseMomentLocale(locale);
m.locale(locale);
// other logic to determine whether to show the time as "9:43 pm", "yesterday", or "7/8/2018"
return formattedTime;
}
/**
* Checks if the device locale is available in moment and returns the locale to be loaded
* <strong i="7">@param</strong> {string} locale locale to be checked
* <strong i="8">@return</strong> {string} locale to be loaded by moment
*/
const chooseMomentLocale = (locale) => {
// make the locale lower case
// will fix crashes caused by "en-GB" (instead of "en-gb") not being found
locale = locale.toLowerCase();
if (moment.locales().includes(locale)) { // check if the locale is included in the array returned by `locales()` which (in this case) tells us which locales moment will support
return locale;
} else if (moment.locales().includes(locale.substring(0, 2))) {
// check if the first two letters of the locale are included in the array returned by `locales()` which (in this case) tells us which locales moment will support
// will fixes crashes caused by "en-US" not being found, as we'll tell moment to load "en" instead
return locale.substring(0, 2);
}
// use "en-gb" (the default language and locale for my app) as a fallback if we can't find any other locale
return 'en-gb';
};
Ich habe dieses Problem auch mit React Native erlebt und konnte es vermeiden, indem ich alle Gebietsschemas neben Moment einbezog, d. H.
import moment from 'moment'
import 'moment/min/locales'
(Alternativ wird auch moment/min/moment-with-locales
bereitgestellt, das jedoch mit einigen unserer anderen Formatierer nicht kompatibel war.)
Dies ist ein super nerviges Problem.
Ist es nicht der springende Punkt bei Gebietsschemas, dass Sie nicht einmal darüber nachdenken müssen und sicher nicht "en-US" in Ihren Code fest codieren, nur weil SIE in den USA sind? Ich verstehe nicht, warum es nicht einfach genommen werden kann, wenn ein Gebietsschema von 'en-US' angefordert wird. Verursacht Menschen endlose Kopfschmerzen.
Ich habe dieses Problem vor einem Jahr gelöst, aber völlig vergessen, wie, dann muss ich von vorne anfangen. (Ich verwende eine Datumsauswahl in Angular und stelle mit diesem Fehler nur die minimale Implementierung in die Luft.)
Ich bekomme dies in Angular und versuche, die Datetime-Auswahl zu verwenden. Wenn ich die LOCALE auf so etwas wie en-GB setze, funktioniert es einwandfrei, aber ohne etwas anzugeben, erhalte ich dies. Ich wünschte, ich könnte herausfinden, wie ich das richtig beheben kann
Für RN habe ich es im Release-Modus zum Laufen gebracht, indem ich zum ersten Teil des Gebietsschemas gewechselt habe (wahrscheinlich, was hinter den Bildschirmen passiert, wenn das Gebietsschema "xx-XX" nicht geladen werden kann). Im folgenden Ausschnitt ist
locale
das Gebietsschema Ihres Geräts in der Form "xx-XX".
moment.locale(locale.indexOf("-") === -1 ? locale : locale.substr(0, locale.indexOf('-')))
Diese Lösung funktioniert für mich mit i18n
und momentjs
wie folgt:
// imports:
import moment from 'moment';
import i18n from './i18n';
import 'moment/locale/fr';
// constructor:
moment.locale(i18n.locale.indexOf('-') === -1 ? i18n.locale : i18n.locale.substr(0, i18n.locale.indexOf('-')));
Ich experimentiere immer noch mit diesem Problem, indem ich die Version "moment" ausführe: "^ 2.22.2",
Irgendeine Korrektur in der letzten Version?
Ich werde mich auf dieses Thema einlassen.
Ich hatte auch diesen Fehler bei der Reaktion auf die Produktion, nachdem ich eine schöne Entwicklung erstellt hatte, die perfekt funktioniert.
Es wurde mit der vorgeschlagenen Lösung @adesmet und dem folgenden Refaktor gelöst:
function parseLocaleForMoment (language) {
if (language.indexOf('-') === -1) return language
else return language.substr(0, language.indexOf('-'))
}
Sieht so aus, als würde RN mit dem Moment so viel saugen, dass es einfacher ist, nur einen nativen Formatierer zu schreiben. Wahrscheinlich nur eine Codezeile, kugelsicher.
Habe es so repariert:
const subLocales = [
'ar-tn',
'ar-dz',
'ar-kw',
'ar-ma',
'ar-sa',
'ar-ly',
'de-at',
'de-ch',
'en-sg',
'en-au',
'en-ca',
'en-gb',
'en-ie',
'en-nz',
'es-us',
'es-do',
'fr-ca',
'fr-ch',
'gom-latn',
'hy-am',
'pa-in',
'pt-br',
'sr-cyrl',
'tl-ph',
'tlh',
'tet',
'ms-my',
'it-ch',
'tzl',
'tzm',
'tzm-latn',
'nl-be',
'ug-cn',
'uz-latn',
'zh-cn',
'zh-hk',
'zh-tw'
];
let momentLocale = i18n.locale.toLowerCase();
if (!subLocales.includes(momentLocale)) {
momentLocale = momentLocale.substring(0, 2);
}
moment.locale(momentLocale);
mit react native @tapz scheint zh
: /
Dies kann daran liegen, dass zh und einige andere Gebietsschemas unterschiedlich formatiert sind, um zwischen vereinfacht und traditionell zu unterscheiden. Siehe https://gist.github.com/jacobbubu/1836273
@ rajivshah3 in der Tat hatte ich zh_Hant_HK
was nicht mit der Tapz-Methode funktionierte. Ich verwende jetzt Ihre Methode, die der beste Weg zu sein scheint, um dieses Problem so reibungslos wie möglich zu lösen, danke für Ihren Beitrag 👍
Gleiches Problem, nur im RN-Produktionsmodus.
Das scheint für mich gut zu funktionieren.
import 'moment/locale/fr';
import 'moment/locale/es';
import 'moment/locale/de';
import 'moment/locale/en-gb';
import 'moment/locale/es-us';
const toMomentLocale = locale => {
let momentLocale = locale;
momentLocale = momentLocale.replace('_', '-').toLowerCase();
momentLocale = ['en-gb', 'en-us'].includes(locale)
? momentLocale
: momentLocale.split('-')[0];
return momentLocale;
};
Solange die Daten importiert werden (oder en
) und den Fall respektieren, scheint es für uns gut zu funktionieren
Das ist wirklich lächerlich. Das Entfernen des Abschnitts -region
des Sprachcodes ist keine Lösung.
1) Sie verlieren die regionale Spezifität des Gebietsschemas.
2) Schlimmer noch, diese Methode führt zu weiteren Abstürzen. Chinesisch ( zh
) zum Beispiel gibt es in den MomentJS-Gebietsschemas nicht einmal. Es sind nur zh-cn
, zh-hk
und zh-tw
definiert. Wenn Sie also den obigen Code verwenden, um Regionen aus der Gebietsschema-Zeichenfolge zu entfernen, stürzt Ihre App auf den meisten chinesischen Geräten sofort ab. Nur knapp 800 Millionen Smartphone-Nutzer.
Meine vorübergehende (und absolut durchgeknallte) Problemumgehung für React Native lautet wie folgt:
const locale = 'zh-cn'; // or en-US etc
const languageCode = moment.locale(locale.indexOf("-") === -1 ? locale : locale.substr(0, locale.indexOf('-'))); // now 'zh', 'en' etc. Thanks <strong i="14">@adesmet</strong>
let momentJsLocale;
switch(languageCode.toLowerCase()) {
case 'zh':
// No 'zh' locale exists in MomentJS. App will crash in production if used.
momentJsLocale = 'zh-cn';
break;
case 'pa':
momentJsLocale = 'pa-in';
break;
case 'hy':
momentJsLocale = 'hy-am';
break;
default:
momentJsLocale = languageCode.toLowerCase();
}
moment.locale(momentJsLocale);
@adammcarth Hallo, haben wir Neuigkeiten zu Moment-Locales, die für RN
Dies ist gerade bei einem Release-Build mit en-gb
abgestürzt.
Ich habe ein ähnliches Problem wie; @simeyla .
Wenn ich Luxon zusammen mit Timepicker hinzufüge, tauchen Probleme auf und sie scheinen mit dem Gebietsschema "en-US" in Zusammenhang zu stehen.
@steveccable Nun, es wird versucht, es zu laden, nur für den Fall, dass Sie eine spezifischere Lokalisierung hatten. Wenn es fehlschlägt, versucht es nur "en" und ist erfolgreich. Ich denke, die Trennung ist nur, dass es irgendwie für Sie kaputt geht, wenn Sie "en-US" nicht laden. Hier soll nichts explodieren; Es soll nur anmutig scheitern und zur nächsten Option
Ein weiteres Problem bei der Behandlung von 'en-US' oder anderen gültigen Gebietsschemas mit Ausnahmen besteht darin, dass Sie beim Debuggen und Auffordern des Debuggers, Ausnahmen zu bremsen, wiederholt an diesem feststecken.
Es sollte einen besseren und einfacheren Weg geben, insbesondere für ein so großes Gebietsschema wie das "en-US".
Letztendlich sollten diese Gebietsschemas mit der Möglichkeit einer großen Zielgruppe / Nutzung vorab überprüft und behandelt werden, um die Geschwindigkeit zu berücksichtigen.
Ich habe die Lösung von @slorber geändert , um robuster zu sein. Dadurch wird ein eingehendes Gebietsschema (z. B. "zh_CN" in "zh-cn") neu formatiert und geprüft, ob es von Ihrer momentanen Installation unterstützt wird, indem Sie auf das Land zurückgreifen und dann auf en-us zurückgreifen.
const toMomentLocale = (locale) => {
let newLocale = locale.replace('_', '-').toLowerCase();
let tryLocales = [newLocale, newLocale.split('-')[0]];
for (let i = 0; i < tryLocales.length; i++) {
if (moment.locales().indexOf(tryLocales[i]) >= 0) return tryLocales[i];
}
return 'en-us';
};
// use it like this:
let m = moment();
m.locale(toMomentLocale('zh_CN')).format('LLL'); // "2019年12月11日上午9点33分" -- used "zh-cn"
moment.locale(toMomentLocale('ja_JP'));
moment().format('LLL') // 2019年12月11日 09:34 -- falls back to "ja"
Gleiches Problem, nur im IOS-Modus der RN-Produktion.
Das scheint für mich gut zu funktionieren.
Moment von "Moment" importieren;
'moment / locale / es' importieren;
Ich habe einige Zeit damit verbracht, dies zu debuggen. Vielen Dank an
Dies ist immer noch ein Problem 😢
Hallo Leute,
Ich habe ein kleines Paket für Sie erstellt -> https://github.com/tonix-tuft/moment-utl
npm install --save moment moment-utl
Sie können Folgendes verwenden, um alle unterstützten aktuellen Gebietsschemas zu ermitteln, ohne sie im Voraus laden zu müssen:
import { allSupportedLocales, allSupportedLocalesMap } from "moment-utl";
const locales = allSupportedLocales(); // As an array: ["af", "ar", "ar-dz", "ar-kw", "ar-ly", "ar-ma", "ar-sa", "ar-tn", "az", "be", "bg", ..., "en", ..., "zh-tw"]
const localesMap = allSupportedLocalesMap(); // As an object: { "af": 1, "ar": 2, "ar-dz": 3, "ar-kw": 4, "ar-ly": 5, "ar-ma": 6, "ar-sa": 7, "ar-tn": 8, "az": 9, "be": 10, ..., "en": 27, "zh-tw": 128 };
moment-utl
Peer hängt von moment
, aber es bündelt alle moment
Gebietsschemas
Nehmen Sie sie aus dem Verzeichnis moment/locale
während Sie ein moment
dev-Abhängigkeitspaket erstellen.
Da moment
eine Peer-Abhängigkeit ist, sollten Sie bei Verwendung von ES6 sicherstellen, dass sowohl allSupportedLocales
als auch allSupportedLocalesMap
aktuelle Gebietsschemas mit moment
Version, die Sie zusammen mit moment-utl
in Ihrem Projekt installiert haben (z. B. wenn moment
eines Tages ein neues Gebietsschema hinzufügt, sollte dies Sie abdecken), können Sie diese Gebietsschemas auch mit dem neu generieren moment-utl-locales
Skript bereitgestellt von moment-utl
.
Sie können es mit dem Befehl npx
:
npm install -g npx # Install npx if you don't have it yet
npx moment-utl-locales # Run this command from your project's root folder
Wenn Sie dieses Skript verwenden, stellen Sie sicher, dass Sie es ausführen, bevor Sie Ihren Code mit Rollup oder Webpack bündeln (je nachdem, was Sie verwenden), damit ein aktuelles Gebietsschema-Array und -Objekt generiert wird, bevor Ihr Bundler auf sie stößt und sie hinzufügt dein letztes Bündel.
Ich hoffe das hilft!
Als Antwort auf @adammcarth überprüfen Sie bitte meine Antwort hier: https://github.com/tonix-tuft/moment-utl/issues/1#issuecomment -616088826
Dieses Problem hat die Leute bei Odoo heimgesucht und die vorgeschlagene Lösung bestand darin, die en-us-Datei manuell zu erstellen. Seufzer.
Was ich nicht verstehe, ist, warum Moment versucht, die en-us-Datei zu laden, wenn der Loader, wie oben erwähnt, wissen sollte, dass er bereits "en" hat, und es nicht dynamisch importieren sollte.
Auf jeden Fall ist es immer noch ein Albtraum für RN-Benutzer. Das Schlimmste ist, dass das Problem nur bei Produktions-Builds auftritt.
Eine versteckte Standardeinstellung ist ein Paket von Überraschungen ...
Dieses Problem hat die Leute bei Odoo heimgesucht und die vorgeschlagene Lösung bestand darin, die en-us-Datei manuell zu erstellen. Seufzer.
Was ich nicht verstehe, ist, warum Moment versucht, die en-us-Datei zu laden, wenn der Loader, wie oben erwähnt, wissen sollte, dass er bereits "en" hat, und es nicht dynamisch importieren sollte.
Auf jeden Fall ist es immer noch ein Albtraum für RN-Benutzer. Das Schlimmste ist, dass das Problem nur bei Produktions-Builds auftritt.
Eine versteckte Standardeinstellung ist ein Paket von Überraschungen ...
Ich werde 👎 dafür bekommen, aber meine Lösung bestand darin, moment
gegen dayjs
auszutauschen. Da sie dieselbe Funktions- / API-Benennung haben, war es für mich so einfach wie ein find all + replace all
.
Ich teile nur mit, was ich für Leute getan habe, die dies in Betracht ziehen möchten.
Hilfreichster Kommentar
@icambron Meine Umgebung ist eine React Native-Anwendung, die npm verwendet, um meine Abhängigkeiten zu steuern, und ich konnte den Fehler auch in minimalen Beispielanwendungen replizieren. Das Problem ist, dass in der Funktion loadLocale versucht wird, ('./ locale /' + name) anzufordern, wobei name en-US ist, und dass dies fehlschlägt. Wenn diese Anforderung in einem Release-Build fehlschlägt, stürzt die App mit einem Stack-Trace ab, wie folgt:
Wenn getLocale den Code durchblättert und feststellt, dass mein Schlüssel ('en-US') kein Array ist, fällt er in loadLocale, ohne jemals zu versuchen, mit 'en' übereinzustimmen, was nur passieren würde, wenn er in die Funktion selectLocale gehen würde.
BEARBEITEN: Nachdem Sie sich die Funktion "ChooseLocale" etwas genauer angesehen haben, wird immer noch versucht, "en-US" zu wählen und dann die Anforderung zu verfehlen, bevor Sie jemals "en" versuchen wenn dies ein Array wäre.
Seltsam ist auch die Tatsache, dass sich die Stelle, an der es bricht, in einem Versuch / Fang befindet und dennoch einen Absturz verursacht. Das ist eigentlich die wirklich verwirrende Sache hier.
BEARBEITEN 2: Beachten Sie, dass die Anforderung in einem Debug-Build (__DEV__) ordnungsgemäß fehlschlägt und dann auf die Verwendung von 'en' zurückzuführen ist. Ich bin mir nicht sicher, warum erfordern in __PROD__ so viel explosiver ist, aber es bricht hier definitiv im Moment.
BEARBEITEN 3: In den erforderlichen js-Dokumenten heißt es: "Wenn Sie die Abhängigkeiten nicht ausdrücken, werden wahrscheinlich Ladefehler angezeigt, da RequireJS Skripte asynchron und aus Geschwindigkeitsgründen nicht in der richtigen Reihenfolge lädt." Daher ist es unwahrscheinlich, dass der Versuch / Fang uns hier tatsächlich rettet, da Versuch / Fang nur bei synchronen Fehlern wirklich hilft.