Ho utilizzato Typescript negli ultimi 3 mesi per creare applicazioni CRUD molto complesse. La sicurezza in fase di compilazione offerta da Typescript ha fornito significativi aumenti di velocità nel mio lavoro: catturare errori in fase di compilazione è una manna dal cielo, rispetto a vederli manifestarsi come eccezioni e comportamenti scorretti in fase di esecuzione.Velocità di compilazione del dattiloscritto: tentativo di soluzione alternativa ma bloccato alla fusione
C'è un problema, però.
Ho a che fare con centinaia di tabelle, quindi sto utilizzando un generatore di codice personalizzato che parte dallo schema DB e genera automaticamente molti file Typescript. Finché lo schema è piccolo, questo funziona perfettamente - ma per uno schema molto grande contenente centinaia di tabelle, il tempo di compilazione di tsc sta diventando un problema - Sto vedendo tempi di compilazione di 15 minuti per un set di 400 file .. . (così come il terribile errore di compilazione di "CALL_AND_RETRY_2 allocazione fallita" - cioè, problemi di memoria ...)
Finora, ho usato tsc in un Makefile, invocandolo con il "tsc" --out ... "sintassi, che genera un singolo .js da tutti i miei file .ts. Ho quindi pensato che avrei potuto risolvere questo problema eseguendo la build in modo incrementale: compilando ogni .ts da solo (cioè passando un solo file .ts in tsc alla volta) e alla fine, concatenando tutti i generati .js in un singolo. Questo infatti sembrava funzionare - solo i file modificati devono essere ricompilati durante lo sviluppo normale (e solo la compilazione iniziale passa attraverso tutti loro, e quindi richiede molto tempo).
ma si è scoperto che anche questo, ha un problema: al fine di rendere ogni ts "standalone-compile-grado", ho dovuto aggiungere tutte le dipendenze rilevanti in cima - vale a dire, le linee come
/// <reference path=...
... sopra ogni file .ts.
E a causa di questi riferimenti, i file .js generati contengono sezioni identiche, che vengono ripetute su molte di esse ... Quindi quando concatenando i file .js, ottengo più definizioni per le stesse funzioni e, peggio, ripetizioni di scope globali (var global = new ...) ripetute!
ho quindi bisogno di un modo per in qualche modo intelligente "fondere" i file generati .js, per evitare di vedere le definizioni di funzioni replicate ...
C'è qualche modo per farlo che si fondono in modo intelligente, evitando le ripetizioni? O forse un altro modo per accelerare la compilazione?
Qualsiasi suggerimento sia il benvenuto ... La velocità di compilazione di tsc è 30-100 volte più lenta dei normali compilatori - è davvero un punto di blocco ora.
UPDATE, 2 giorni dopo
Basarat (vedere la sua risposta qui sotto) mi ha aiutato a applicare la sua soluzione nel mio progetto. Si scopre che anche se la sua soluzione funziona perfettamente con progetti di piccole e medie dimensioni, con la mia ho avuto il temuto errore "FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory" - che è lo stesso errore che ottengo quando uso "tsc --out ... ".
Alla fine, la mia soluzione Makefile-based è l'unica cosa che ha funzionato - farlo in questo modo:
%.js: %.ts
@UPTODATE=0 ; \
if [ -f "$<".md5 ] ; then \
md5sum -c "$<".md5 >/dev/null 2>&1 && { \
UPTODATE=1 ; \
} ; \
fi ; \
if [ $$UPTODATE -eq 0 ] ; then \
echo Compiling $< ; \
tsc --sourcemap --sourceRoot /RevExp/src/ --target ES5 $< || { \
rm [email protected] "$<".md5 ; \
exit 1 ; \
} ; \
md5sum "$<" > "$<".md5 ; \
fi
...che fa due cose: usa i checksum MD5 per capire quando effettivamente eseguire una compilation, e fa la compilazione in modo "standalone" (cioè senza l'opzione "--out" di tsc).
Nella regola obiettivo reale, ho usato per unire i file generati Js ... ma questo mi ha lasciato senza lavorare file .map (per il debug) - così ora generato include diretto nel index.html:
${WEBFOLDER}/index.html: $(patsubst %.ts,%.js,${CONTROLLERS_SOURCES}) ${WEBFOLDER}/index.html.template
cat ${WEBFOLDER}/index.html.template > [email protected] || exit 1
REV=$$(cat revision) ; \
for i in $(patsubst %.ts,%.js,${CONTROLLERS_SOURCES}) ; do \
BASE=$$(basename $$i) ; \
echo " <script type='text/javascript' src='js/$${BASE}?rev=$$REV'></script>" >> [email protected] ; \
done || exit 1
cat RevExp/templates/index.html.parallel.footer >> [email protected] || exit 1
cp $(patsubst %.ts,%.js,${CONTROLLERS_SOURCES}) ${WEBFOLDER}/js/ || exit 1
lascerò la questione aperta per i contributi futuri ...
Questo mi sembra una buona opzione –
Basarat mi ha aiutato a applicare la sua soluzione nel mio progetto - ma si scopre che anche se funziona perfettamente con progetti di piccole/medie dimensioni, ho ricevuto il solito "ERRORE FATALE: CALL_AND_RETRY_2 Assegnazione fallita - processo a memoria insufficiente" quando l'ho provato con il mio progetto. Alla fine, la mia soluzione basata su Makefile è l'unica cosa che ha funzionato: correggerò la domanda con la mia soluzione e la lascerò aperta per i contributi futuri ... – ttsiodras
@ttsiodras puoi provare l'ultima versione? TS 1.0 + è stato aggiunto un nuovo predefinito di compilazione veloce – basarat