puis-je désactiver l'optimisation, de sorte que les variables de portée des fermetures ne sont pas «optimisées»

11

En tant que sous-produit de l'optimisation de code effectuée par les navigateurs modernes, lors du débogage, vous ne pouvez pas "voir" toutes les variables qui "en fait" sont dans la portée. Ceci est bien connu et a été abordé dans une question précédente sur SO . Cette fonctionnalité, bien que très certainement utile en production, me gêne beaucoup pendant le développement, elle me ralentit (cela devrait être évident.)

Maintenant, ma question est, existe-t-il un moyen de désactiver ce comportement? Puis-je modifier un fichier de configuration, ou existe-t-il un plugin de navigateur, ou peut-être qu'il existe une "version de construction spéciale pour les développeurs" de l'exécutable du navigateur? J'adore taper mon code dans la console tout de suite lorsque j'écris du nouveau code, donc cela me dérange vraiment.

visualSummaryIffalseConsoleLog

MISE À JOUR / MODIFICATION

Voici une solution partielle, crédit à Paul1365972.

Vous devez démarrer le navigateur Chrome à partir de la ligne de commande, avec des options spéciales, comme ceci:

  1. Fermer complètement Chrome
  2. Exécutez Chrome à partir de la console avec un "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" --js-flags="--allow-natives-syntax" système d'exploitation similaire à Windows.
  3. Ouvrez la console développeur et exécutez "%GetHeapUsage()". Si vous avez correctement démarré Chrome avec l'option, un numéro sera enregistré dans la console, sinon vous obtiendrez une erreur de syntaxe.

Avec cet indicateur de ligne de commande, vous pouvez «parler au moteur V8» avec des commandes commençant par %, qui sont des erreurs de syntaxe en JavaScript simple. Une liste des commandes V8 disponibles de ce type a été donnée dans la réponse de Paul .

Il y a %NeverOptimizeFunction()sur cette liste, quelque chose qui ressemblait à ce que je devais appeler et en finir. Malheureusement, cette fonction ne fait pas ce que j'espérais, comme le montre la capture d'écran suivante.

Lorem toujours pas défini

(((L' autre lien de la réponse de Paul (module de noeud v8-natives) n'a pas d'importance pour nous ici dans ce contexte. Tout ce qu'il fait, c'est qu'il enveloppe les lignes simples autour des appels de fonction "%" afin que le code ne plante pas navigateurs qui ne sont pas v8.)))

(((Je me souviens d'un moment où cela a fonctionné (où cette optimisation n'a pas encore été inventée / implémentée). Je ne sais pas depuis combien de temps. Dix ans? 15 ans? Quelque chose comme ça. Quelle était la dernière version de Chrome (si ) et quelle était la dernière version de Firefox (plus sûre ici qu'elle existe) où vous pouviez faire? Cela ne vous rapportera pas la prime, mais cela vous donnera un vote positif, si vous le savez et le postez comme réponse .)))

LA SOLUTION

MERCI PETR SRNICEK

correction hacky

NOUVELLE QUESTION

Bien que la solution de Petr aide beaucoup, elle n'est pas parfaite. Cette question devient trop longue, j'ai donc posté une nouvelle question sur la façon dont la solution de Petr peut être améliorée. (Je pourrais bien sûr éditer cette question ici, mais cela me semblerait "non historique", si vous voyez ce que je veux dire.)

mathheadinclouds
la source
conséquences imprévues, chapitre dix mille. cette optimisation a un effet négatif sur mon style de codage. Je me retrouve à utiliser l'ancienne boucle for (au lieu de .map, .forEach, .reduce) plus que je ne le ferais autrement, juste pour éviter d'éviter de rencontrer ce problème.
mathheadinclouds
La v8-nativesbibliothèque enveloppe simplement les% d'appels importants dans le code dans une bibliothèque simple qui devrait être noopsdans un navigateur ou un noeud qui n'a pas été démarré dans le drapeau spécial --allow-natives-syntax ..
Nathanael
J'ai fait quelques tests, la fonction 'bodyOnLoad' n'est de toute façon pas optimisée; donc utiliser les commandes internes pour essayer de la forcer à désoptimiser ne fait rien.
Nathanael
@Nathanael: L'appel important est que %NeverOptimizeFunction(foo)je l'ai appelé aussi pour bodyOnload, "juste parce que", pensant "bien, ça ne fera pas mal". Le problème est que ce foon'est PAS désoptimisé comme je l'espérais. La variable loremest invisible. Disons que je veux écrire le code qui doit aller dans la fonction foo. Au lieu de le taper dans mon éditeur de texte, je le tape dans la console de développement (pendant que le débogueur est assis sur foo), voir s'il fait ce que je veux, puis le copier / coller de la console dans mon éditeur de texte. C'est comme ça que j'aime travailler. Et je ne peux pas. En raison de l'optimisation. Tu piges?
mathheadinclouds
1
J'ai passé plusieurs des nôtres à expérimenter diverses --js-flags(dont plusieurs liées à TurboFan ) ainsi que plusieurs commandes natives V8 avant que Paul1365972 ne publie sa réponse, mais je n'ai pas pu obtenir le comportement souhaité. Je pense que cette approche pourrait être une impasse. Il pourrait être utile d'ajouter une [v8]balise à cette question. Quelqu'un avec une compréhension approfondie du fonctionnement interne du V8 pourrait être en mesure de clarifier si c'est la voie à suivre ou peut-être vous orienter dans la bonne direction.
Petr Srníček

Réponses:

2

Vous pouvez accéder à toutes les variables en enroulant l'instruction debugger dans un eval comme ceci: eval("debugger;");. Cette solution hacky ajoute une autre fonction anonyme à la pile d'appels et elle n'est évidemment d'aucune utilité pour les points d'arrêt définis manuellement dans DevTools.

Cela ne semble pas être une très bonne solution, mais comme c'est le seul qui atteint le comportement souhaité jusqu'à présent, je le poste comme réponse.

Petr Srníček
la source
cela me surprend un peu que cela fonctionne. Vous savez, j'ai essayé de taper eval ("lorem"), et cela a donné la même erreur "lorem is not defined". Cela n'a pas beaucoup de sens pour moi que taper eval ("lorem") sur la console (alors que sur l'instruction de débogage dans la fonction foo) devrait faire quelque chose de différent de ce que fait eval ("débogueur") - attendez-vous, imprimez "ipsum" à la console. Mais ils sont très différents. Étrange.
mathheadinclouds
C'est un travail intéressant. C'est un peu hacky, car vous ne pouvez pas sortir de l'instruction de débogage (il vous suffit de basculer manuellement vers le fichier source) sinon vous perdez la pile entière et revenez à la fonction qui a appelé l'eval; vous laissant la pile réduite manquant l'autre contexte.
Nathanael
on peut modifier cette astuce ainsi: au lieu d'eval ("debugger"), mettez juste eval ("") - mais beaucoup d'entre eux, répartis dans tout le code, partout où vous pensez que vous voudrez peut-être un 'point d'arrêt étendu'. Vous pouvez ensuite définir un point d'arrêt (avec les outils de développement) où se trouve l'une de ces instructions eval (''), et une fois que vous vous arrêtez là, vous "entrez". J'envisage d'écrire un petit transpilateur (gros mot pour une petite chose que je fais) en mettant ces instructions au début de chaque fonction. stackoverflow.com/questions/59159996/…
mathheadinclouds
J'ai juste essayé de remplacer eval ("debugger") par eval (); débogueur, et a obtenu des résultats différents, selon l'utilisation de Firefox ou de Chrome. i.stack.imgur.com/wy5WT.png
mathheadinclouds
3

Google Chrome utilise le moteur V8 JS-Engine, vous pouvez activer les appels natifs avec le drapeau --allow-natives-syntax, cela expose de nombreuses fonctions de débogage utiles (liste complète ici ) comme celle que vous recherchez:% NeverOptimizeFunction () . Sans cet indicateur, ces appels seraient une syntaxe illégale, alors soyez prudent lors du déploiement (ou utilisez la bibliothèque v8-Natives ).

Pour activer cette fonctionnalité, ouvrez simplement chrome avec --js-flags = "- allow-natives-syntax" (utilisez-le uniquement pour le débogage de sites Web de confiance, car cela peut donner au code js un accès non fiable à des choses que vous ne voulez vraiment pas avoir accès à).

Paul1365972
la source
Merci. Veuillez lire ma question mise à jour. Il semble très probable que vous ayez la solution ici, mais j'ai besoin de plus d'éclaircissements pour la faire fonctionner. Si cela fonctionne, vous méritez certainement la prime.
mathheadinclouds
tl; dr utilisez plutôt --js-flags = "- allow-natives-syntax". Pour activer la fonctionnalité, le moteur V8 JS doit être démarré avec l'indicateur --allow-natives-syntax, mais vous ne pouvez pas le démarrer directement, c'est le travail chromes. Vous devez donc dire à Chrome de démarrer le moteur avec le drapeau, comment faites-vous cela? Passez simplement le drapeau du moteur mentionné via --js-flags = <votre drapeau ici> à chrome.
Paul1365972
Nan. Je viens juste d'essayer ça encore une fois, pour être du côté sûr. J'ai essayé à la fois --allow-natives-syntaxet --js-flags="--allow-natives-syntax"plusieurs fois comme "la chose que je tape après" chrome "dans la console du système d'exploitation". Si je n'avais pas tout essayé moi-même, moi aussi je pense qu'une faute de frappe est l'explication la plus probable. J'ai fait une autre capture d'écran. i.stack.imgur.com/7cpPP.png Vous voyez une faute de frappe? S'il vous plaît, donnez-moi une réponse honnête: avez-vous juste "lu et compris l'article" (pour être clair, rien de mal à cela, si vous n'en réclamez pas plus), ou avez-vous réellement essayé tout cela sur votre machine? thx
mathheadinclouds
juste une supposition: se pourrait-il que je ne démarre pas l'exécutable chrome avec cette option, mais que je compile les sources chrome C ++ (ou autre) avec cette option?
mathheadinclouds
1
C'est étrange, je viens de le tester et cela a bien fonctionné, aucune compilation n'est nécessaire. Je vais juste écrire exactement ce que j'ai fait pour qu'il n'y ait aucun malentendu. 1. Fermez complètement Chrome 2. Exécutez Chrome à partir de la console avec "C: / Program Files (x86) /Google/Chrome/Application/chrome.exe" --js-flags = "- allow-natives-syntax" 3. Ouvrez console du développeur et exécutez "% GetHeapUsage ()" pour tester si tout fonctionne
Paul1365972
0

J'espère vraiment que cette question a une VRAIE réponse. Ce qui suit n'est pas une vraie réponse, c'est une fortune. J'ai écrit un outil d'aide avec lequel vous pouvez créer un code d'aide stupide du formulaire if (false) { console.log(variables, from, closures); }(voir la capture d'écran en question) en utilisant une analyse statique - vous collez votre code, la déclaration stupide est créée, vous pouvez la copier, puis vous n'avez pas besoin pour le taper. Je ne sais pas si cela aide beaucoup, car tout ce copier-coller prend aussi du temps, mais c'est ce que j'ai obtenu.

capture d'écran

violon

mathheadinclouds
la source