Lors de l'utilisation de react-native 0.59.10 et de la définition des paramètres régionaux pour momentJS, nous avons détecté un crash très brutal pour nos versions de version uniquement. Ce plantage n'était pas reproductible pour nous avec le débogueur attaché. Ce crash s'est produit pour nous à la fois sur iOS et Android. Les instructions try-catch enveloppant toute l'utilisation du moment n'ont pas détecté le plantage !
Reproduire
["fr-CA", "en-US", "fr", "en"]
moment.locale(localeCandidate)
dans un bloc try-catch, l'application plante toujours sur cette ligne⁇Il s'agissait d'un crash au lancement, mais uniquement pour les versions Release !! Cela rendait très difficile l'extraction des messages d'erreur/journalisation utiles.
Nous avons vu les messages d'erreur suivants via notre intégration Bugsnag et la journalisation de la console système
Exception in HostFunction: Error loading module0from RAM Bundle: unspecified iostream_category error
Exception in HostFunction: Module not found: 0
Requiring unknown module "./locale/en-us".
-- mais étrangement, cette erreur n'était pas traitée en temps opportun. Peut-être un problème de réaction native / bugsnag.Solution : la mise en commentaire de ces deux lignes a interrompu le plantage !
Comportements attendus
require()
dans Release)Smartphone (veuillez compléter les informations suivantes) :
Environnement spécifique à un moment
Veuillez exécuter le code suivant dans votre environnement et inclure la sortie :
console.log([
new Date().toString(),
new Date().toLocaleString(),
new Date().getTimezoneOffset(),
navigator && navigator.userAgent, // react-native might not have a navigator
moment.version,
]);
Sortir:
[
"Wed Oct 09 2019 18:52:16 GMT-0700 (PDT)",
"09/10/2019 à 18:52:16", // This particular device is configured as fr-FR
420,
null,
"2.24.0"
]
Contexte supplémentaire
Les lignes référencées essaient "automatiquement" d'exiger des modules au moment de l'exécution, mais la documentation des paramètres régionaux de chargement indique que si vous utilisez un gestionnaire de packages comme JSPM, vous pouvez charger les paramètres régionaux de import "moment/locale/fr
. Étant donné que nous avons besoin que le gestionnaire de packages react-native "sache" que le fichier doit être importé, nous avons essayé ce style d'importation afin que le packager puisse "voir" tous les fichiers qui doivent être regroupés.
En fin de compte, nos lignes d'importation ressemblaient à ceci :
import moment from "moment";
import "moment/min/locales"; // Import all moment-locales -- it's just 400kb
import "moment-timezone";
L'implémentation exacte de require()
est injectée par l'environnement d'exécution avec lequel vous travaillez, et c'est certainement quelque chose qui se comporte de manière significativement différente entre les versions Debug & Release.
Dans react-native, il existe également plusieurs variantes de regroupement JavaScript en mode Release, notamment des fichiers tout-en-un, des fichiers tout-en-un et des ensembles RAM. Chacun d'entre eux modifie également le fonctionnement de require. Debug require()
connecte au Metro Bundler exécuté sur un serveur http local. C'est probablement très similaire aux serveurs de débogage webpack/jspm/autres, c'est probablement pourquoi l'aliasing require ne pose pas de problèmes dans cet environnement.
A. Supprimer complètement le aliasedRequire
si ce n'est plus comme ça que vous êtes censé faire les choses + modifier les instructions d'installation à ce sujet ?
B. Détecter react-native vs navigateur ( navigator
n'est pas disponible dans react-native, mais il existe d'autres techniques ici), et se comporter différemment selon la situation dans laquelle nous nous trouvons ? par exemple. si react-native && DEV, imprimez une console.error si la locale est théoriquement prise en charge, mais n'a pas encore été required
(+ mettre à jour la documentation).
C. Déplacez le aliasedRequire
d'une variable locale dans cette fonction vers un "semi-global". moment.aliasedRequire
, de cette façon, nous pourrions injecter une fonction no-op/do-nothing afin que aliasedRequire
ne puisse plus provoquer le crash dur de react-native.
Je serais heureux d'implémenter l'une de ces options si un responsable peut m'indiquer laquelle il aimerait que j'implémente, et pour les propositions B/C, aidez-moi à affiner l'implémentation exacte qu'il serait enclin à accepter !
@marwahaha --
Commentaire le plus utile
Les lignes référencées essaient "automatiquement" d'exiger des modules au moment de l'exécution, mais la documentation des paramètres régionaux de chargement indique que si vous utilisez un gestionnaire de packages comme JSPM, vous pouvez charger les paramètres régionaux de
import "moment/locale/fr
. Étant donné que nous avons besoin que le gestionnaire de packages react-native "sache" que le fichier doit être importé, nous avons essayé ce style d'importation afin que le packager puisse "voir" tous les fichiers qui doivent être regroupés.En fin de compte, nos lignes d'importation ressemblaient à ceci :
L'implémentation exacte de
require()
est injectée par l'environnement d'exécution avec lequel vous travaillez, et c'est certainement quelque chose qui se comporte de manière significativement différente entre les versions Debug & Release.Dans react-native, il existe également plusieurs variantes de regroupement JavaScript en mode Release, notamment des fichiers tout-en-un, des fichiers tout-en-un et des ensembles RAM. Chacun d'entre eux modifie également le fonctionnement de require. Debug
require()
connecte au Metro Bundler exécuté sur un serveur http local. C'est probablement très similaire aux serveurs de débogage webpack/jspm/autres, c'est probablement pourquoi l'aliasing require ne pose pas de problèmes dans cet environnement.