posso disattivare l'ottimizzazione, quindi le variabili nell'ambito delle chiusure non sono "ottimizzate"


11

Come sottoprodotto dell'ottimizzazione del codice eseguita dai browser moderni, durante il debug, non è possibile "vedere" tutte le variabili che "di fatto" rientrano nell'ambito. Questo è ben noto ed è stato affrontato in una domanda precedente qui su SO . Questa caratteristica, anche se sicuramente utile in produzione, mi sta infastidendo molto durante lo sviluppo, mi rallenta (dovrebbe essere ovvio).

Ora la mia domanda è: c'è un modo per disattivare questo comportamento? Posso modificare alcuni file di configurazione, oppure esiste un plug-in del browser o forse esiste una "versione di build speciale per gli sviluppatori" dell'eseguibile del browser? Adoro digitare il mio codice nella console immediatamente quando scrivo un nuovo codice, quindi questo mi sta davvero infastidendo.

visualSummaryIffalseConsoleLog

AGGIORNAMENTO / MODIFICA

Ecco una soluzione parziale, merito a Paul1365972.

Devi avviare il browser Chrome dalla riga di comando, con opzioni speciali, in questo modo:

  1. Chiudi Chrome completamente
  2. Esegui Chrome dalla console con "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" --js-flags="--allow-natives-syntax" Windows per altri sistemi operativi simili.
  3. Apri la console per gli sviluppatori ed esegui "%GetHeapUsage()". Se hai avviato correttamente Chrome con l'opzione, un numero verrà registrato sulla console, altrimenti otterrai un errore di sintassi.

Con questo flag della riga di comando, puoi "parlare al motore V8" con i comandi che iniziano con %, che sono errori di sintassi in JavaScript semplice. Un elenco di comandi V8 disponibili di questo tipo è stato fornito nella risposta di Paul .

C'è %NeverOptimizeFunction()in quella lista, che è qualcosa che assomiglia alla cosa che dovrei solo chiamare e farla finita. Sfortunatamente, quella funzione non fa quello che speravo, come dimostrato nel prossimo screenshot.

il lorem non è ancora definito

(((L' altro link dalla risposta di Paul (modulo nodo v8-natives) non ha importanza per noi qui in questo contesto. Tutto ciò che fa è avvolgere una linea attorno alle chiamate della funzione "%" in modo che il codice non si blocchi browser che non sono v8.)))

(((Ricordo un momento in cui ha funzionato (quando questa ottimizzazione non è stata ancora inventata / implementata). Non so quanto tempo fa. Dieci anni? 15 anni? Qualcosa del genere. Qual era l'ultima versione di Chrome (se qualsiasi) e qual è stata l'ultima versione di Firefox (più sicuro qui che esiste) dove potresti fare? Non ti darà la generosità, ma ti darà un voto, se ti capita di saperlo e pubblicarlo come una risposta .)))

LA SOLUZIONE

GRAZIE PETR SRNICEK

hacky fix

NUOVA DOMANDA

Mentre la soluzione di Petr aiuta molto, non è perfetta. Questa domanda sta diventando troppo lunga, quindi ho pubblicato una nuova domanda su come migliorare la soluzione di Petr. (Potrei ovviamente modificare questa domanda qui, ma sembrerebbe "non storico", se capisci cosa intendo.)


conseguenze indesiderate, capitolo decine di migliaia. questa ottimizzazione ha un effetto negativo sul mio stile di codifica. Mi ritrovo a utilizzare il vecchio ciclo di ciclo (invece di .map, .forEach, .reduce) più di quanto farei altrimenti, solo per evitare di imbattermi in questo problema.
matematica include il

La v8-nativeslibreria avvolge l'importante% di chiamate in codice in una semplice libreria che dovrebbe trovarsi noopsin un browser o nodo che non è stato avviato nella speciale bandiera --allow-natives-sintassi ..
Nathanael,

Ho eseguito alcuni test, la funzione 'bodyOnLoad' non è comunque ottimizzata; quindi usare i comandi interni per provare a forzarlo a non ottimizzare non fa nulla.
Nathanael,

@Nathanael: L'importante è che l' %NeverOptimizeFunction(foo)ho appena chiamato anche per bodyOnload, "solo perché", pensando "bene, non farà male". Il problema è che fooNON è ottimizzato nel modo in cui speravo. La variabile loremè invisibile. Diciamo che voglio scrivere un po 'di codice che deve entrare in funzione pippo. Invece di digitarlo nel mio editor di testo, lo digito nella console di sviluppo (mentre il debugger è seduto su foo), vedo se fa quello che voglio e poi lo copia / incolla dalla console al mio editor di testo. È così che amo lavorare. E non posso. A causa dell'ottimizzazione. Prendilo?
matematica include il

1
Ho trascorso molti dei nostri esperimenti con vari --js-flags(inclusi diversi relativi a TurboFan ) e con diversi comandi nativi V8 prima che Paul1365972 pubblicasse la sua risposta, ma non ero in grado di ottenere il comportamento desiderato. Credo che questo approccio potrebbe essere un vicolo cieco. Potrebbe essere utile aggiungere un [v8]tag a questa domanda. Qualcuno con una profonda comprensione del funzionamento interno di V8 potrebbe essere in grado di chiarire se questa è la strada da percorrere o forse indicarti la direzione corretta.
Petr Srníček,

Risposte:


2

È possibile ottenere l'accesso a tutte le variabili avvolgendo l'istruzione debugger in un eval in questo modo: eval("debugger;");. Questa soluzione hacky aggiunge un'altra funzione anonima allo stack di chiamate ed è ovviamente inutile per i punti di interruzione impostati manualmente in DevTools.

Questa non sembra essere un'ottima soluzione, ma dal momento che è l'unica a raggiungere finora il comportamento previsto, la sto pubblicando come risposta.


mi sorprende che funzioni. Sai, ho provato a digitare eval ("lorem"), e questo ha dato lo stesso errore "lorem non definito". Non ha molto senso per me che digitare eval ("lorem") sulla console (mentre sull'istruzione debugger nella funzione pippo) dovrebbe fare qualcosa di diverso da quello che sta facendo eval ("debugger") - aspettarsi, stampare "ipsum" alla console. Ma sono molto diversi. Strano.
matematica compresa il

È una soluzione interessante. È un po 'confuso, poiché non è possibile uscire dall'istruzione debugger (è sufficiente passare manualmente al file di origine), altrimenti si perde l'intero stack e si ritorna alla funzione che ha chiamato eval; lasciandoti lo stack ridotto mancante nell'altro contesto.
Nathanael,

si può modificare questo trucco in questo modo: invece di eval ("debugger"), metti solo eval ("") - ma molti di loro, distribuiti in tutto il codice, ovunque dove pensi di poter desiderare un "breakpoint esteso". È quindi possibile impostare un punto di interruzione (con gli strumenti dev) in cui si trova una di quelle istruzioni eval (''), e una volta che ci si ferma lì, si "entra". Sto pensando di scrivere un piccolo transpiler (parola grossa per una piccola cosa che sto facendo) mettendo queste dichiarazioni all'inizio di ogni funzione. stackoverflow.com/questions/59159996/...
mathheadinclouds

Ho appena provato a sostituire eval ("debugger") con eval (); debugger e ha ottenuto risultati diversi, a seconda dell'utilizzo di Firefox o Chrome. i.stack.imgur.com/wy5WT.png
mathheadinclouds

3

Google Chrome utilizza V8 JS-Engine, puoi abilitare le chiamate native con il flag --allow-natives-sintassi, questo espone molte utili funzioni di debug (elenco completo qui ) come quello che stai cercando:% NeverOptimizeFunction () . Senza questo flag, queste chiamate sarebbero sintassi illegali, quindi fai attenzione durante la distribuzione (o usa la libreria v8-Natives ).

Per abilitare questa funzione basta aprire Chrome con --js-flags = "- allow-natives-sintassi" (utilizzalo solo per il debug di siti Web attendibili, in quanto ciò può dare accesso al codice js non attendibile a cose che davvero non vuoi che siano avere accesso a).


grazie. Si prega di leggere la mia domanda aggiornata. Sembra abbastanza probabile che tu abbia la soluzione qui, ma ho bisogno di ulteriori chiarimenti per farlo funzionare. Se funziona, meriti sicuramente la taglia.
matematica include il

tl; dr usa invece --js-flags = "- allow-natives-syntax". Per abilitare la funzione, V8 JS-Engine deve essere avviato con il flag --allow-natives-syntax, tuttavia non è possibile avviarlo direttamente, questo è il lavoro di chromes. Quindi devi dire a Chrome di avviare il motore con la bandiera, come lo fai? Basta passare la bandiera del motore menzionata tramite --js-flags = <la tua bandiera qui> a Chrome.
Paul1365972,

no. L'ho appena provato ancora una volta, per essere una parte sicura. Ho provato sia --allow-natives-syntaxe --js-flags="--allow-natives-syntax"più volte come "il tipo I cosa dopo 'chrome' nella console del sistema operativo". Se non avessi provato tutto da solo, anche io penserei che un errore di battitura sia la spiegazione più probabile. Ho fatto un altro screenshot. i.stack.imgur.com/7cpPP.png Hai visto un errore di battitura? Per favore, dammi una risposta onesta: hai appena "letto e compreso l'articolo" (per essere chiari, niente di sbagliato in questo, se non pretendi di più), o hai davvero provato tutto ciò sulla tua macchina? thx
mathheadinclouds

solo un'ipotesi: è possibile che non avvii l'eseguibile di Chrome con quell'opzione, ma che compili i sorgenti di Chrome C ++ (o qualsiasi altra cosa) con quell'opzione?
matematica compresa il

1
È strano, l'ho appena provato e ha funzionato bene, non è necessaria la compilazione. Scriverò esattamente quello che ho fatto in modo che non ci siano equivoci. 1. Chiudi Chrome completamente 2. Esegui Chrome dalla console con "C: / Programmi (x86) /Google/Chrome/Application/chrome.exe" --js-flags = "- allow-natives-syntax" 3. Apri console degli sviluppatori ed esegui "% GetHeapUsage ()" per verificare se tutto funziona
Paul1365972

0

Spero davvero che questa domanda abbia una risposta REALE. Ciò che segue non è una vera risposta, è un caso. Ho scritto uno strumento di aiuto con il quale è possibile creare stupidi codici helper del modulo if (false) { console.log(variables, from, closures); }(vedere la schermata in questione) utilizzando l'analisi statica: si incolla il codice, viene creata la stupida dichiarazione, è possibile copiarlo, quindi non è necessario per digitarlo. Non so se sia di grande aiuto, dal momento che anche tutte queste operazioni di copia e incolla richiedono tempo, ma è quello che ho ottenuto.

immagine dello schermo

violino

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.