Enorme numero di file generati per ogni progetto angolare


594

Volevo avviare una semplice app Hello World per Angular.

Quando ho seguito le istruzioni nella guida rapida ufficiale, l'installazione ha creato 32.000 file nel mio progetto.

Ho pensato che questo fosse un errore o mi mancasse qualcosa, quindi ho deciso di usare angular-cli , ma dopo aver impostato il progetto ho contato 41.000 file.

Dove ho sbagliato? Mi sto perdendo qualcosa di veramente ovvio?


98
È normale per i progetti basati su NPM.
Everettss,

115
@hendrix perché la mia distribuzione (google app engine) consente solo 10K file
Moshe Shaham,

49
Per chiunque fosse curioso del numero di voti su questa domanda e le sue risposte, questo ha reso la prima pagina di HN. news.ycombinator.com/item?id=12209028
ceejayoz

50
@hendrix - Scommetto che impegnerai anche i file .DS_Store su git.
Martin Konecny,

61
Penso che "Se la tua app Hello World funziona, tutto va bene" non è una buona filosofia da seguire, soprattutto per chi sta imparando. L'OP ha esattamente ragione di chiedersi perché siano stati creati così tanti file. L'esempio stesso fa riferimento solo a 5 file. E onestamente, qualsiasi applicazione che ha più file di quante siano le lettere nel suo output dovrebbe essere messa in discussione.
Shawn,

Risposte:


362

Non c'è niente di sbagliato nella tua configurazione.

Angular (dalla versione 2.0) utilizza moduli npm e dipendenze per lo sviluppo. Questa è l'unica ragione per cui stai vedendo un numero così grande di file.

Una configurazione di base di Angular contiene transpiler, dipendenze delle tipizzazioni che sono essenziali solo a scopo di sviluppo.

Una volta terminato lo sviluppo, tutto ciò che dovrai fare è raggruppare questa applicazione.

Dopo aver raggruppato la tua applicazione, ci sarà solo un bundle.jsfile che potrai quindi distribuire sul tuo server.

'transpiler' è solo un compilatore, grazie a @omninonsense per averlo aggiunto.


7
In genere porta anche i dati di test e i test e crea strumenti per le dipendenze e le loro dipendenze e così via.
Benjamin Gruenbaum,

63
Un "transpiler" è solo un compilatore.
omninonsense,

32
ma viene compilato in un'altra lingua anziché in codice byte o codice macchina
Hunter McMillen,

32
@HunterMcMillen Il codice byte e / o il codice macchina è un'altra lingua. Il termine "transpiler" non ha alcun significato aggiuntivo rispetto a "compilatore".
Brandon Buck,

76
Per quanto riguarda tutti i soggetti coinvolti, non sono sicuro che l'argomento semantico sia realmente rilevante per la domanda di OP ^^
Dan Pantry,

144
                                Typical Angular2 Project

                       File del                   pacchetto NPM (sviluppo) File del mondo reale (distribuzione)

@angular                       3,236                             1
rxJS                           1,349                             1*
core-js                        1,341                             2
typings                        1,488                             0
gulp                           1,218                             0
gulp-typescript                1,243                             0
lite-server                    5,654                             0
systemjs-builder               6,470                             0
__________________________________________________________________
Total                         21,999                             3  

*: bundled with @angular

[ vedi questo per il processo di raggruppamento ⇗ ]


24
Suppongo siano -3stati dati per non aver fatto la somma, ma ora ho :)
Ankit Singh

1
cosa intendi per file del mondo reale?
Sì,

1
@yeahman "file del mondo reale" è il numero di file quando il progetto viene distribuito o in produzione .
Maarti,

Anche il conteggio delle dimensioni, solo 3 file, ma possono essere enormi (per il web)
pdem

51

Non c'è nulla di sbagliato nella configurazione di sviluppo .

Qualcosa non va nella tua configurazione di produzione .

Quando si sviluppa un "Progetto Angular 2" o "Qualsiasi progetto basato su JS" è possibile utilizzare tutti i file, è possibile provare tutti i file, è possibile importare tutti i file. Ma se vuoi servire questo progetto devi combinare tutti i file strutturati e sbarazzarti di file inutili.

Esistono molte opzioni per combinare questi file:


2
Non è necessario (citazione necessaria) concatenare i file insieme sul server. Al massimo, userei un transpiler.
Dan Pantry,

1
@DanPantry Transpilers sono compilatori da fonte a fonte. Penso che possano cambiare solo "X" in "JS". I conteggi dei file sono gli stessi.
uragano

1
..Sì, ma non sono sicuro del tuo punto. Il mio punto è che probabilmente non dovresti provare a minimizzare il codice del server (concatenando i file e riducendo così le dimensioni del file). Al massimo, dovresti usare Babel sul tuo codice se stai usando funzionalità di sanguinamento come asincrono / wait.
Dan Pantry,

2
@DanPantry Sono d'accordo con te. Ma sull'interrogatore commenti dice "perché la mia distribuzione (motore di app di Google) consente solo 10K file". In queste condizioni è necessario ridurre al minimo il numero di file.
uragano

4
Sono d'accordo con te ma OP sembra avere un problema con XY qui
Dan Pantry,

30

Come diverse persone hanno già detto: tutti i file nella directory node_modules (posizione NPM per i pacchetti) fanno parte delle dipendenze del progetto (le cosiddette dipendenze dirette). In aggiunta a ciò, le tue dipendenze possono anche avere le loro dipendenze e così via, ecc. (Le cosiddette dipendenze transitive). Diverse diecimila file non sono niente di speciale.

Dato che ti è permesso caricare solo 10'000 file (vedi commenti), andrei con un motore bundler. Questo motore raggrupperà tutto il tuo JavaScript, CSS, HTML, ecc. E creerà un singolo pacchetto (o più se li specifichi). Il tuo index.html caricherà questo bundle e il gioco è fatto.

Sono un fan del webpack, quindi la mia soluzione webpack creerà un bundle di applicazioni e un bundle di fornitori (per l'applicazione completa di lavoro consultare qui https://github.com/swaechter/project-collection/tree/master/web-angular2- esempio ):

index.html

<!DOCTYPE html>
<html>
<head>
    <base href="/">
    <title>Webcms</title>
</head>
<body>
<webcms-application>Applikation wird geladen, bitte warten...</webcms-application>
<script type="text/javascript" src="vendor.bundle.js"></script>
<script type="text/javascript" src="main.bundle.js"></script>
</body>
</html>

webpack.config.js

var webpack = require("webpack");
var path = require('path');

var ProvidePlugin = require('webpack/lib/ProvidePlugin');
var CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
var UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');

/*
 * Configuration
 */
module.exports = {
    devtool: 'source-map',
    debug: true,

    entry: {
        'main': './app/main.ts'
    },

    // Bundle configuration
    output: {
        path: root('dist'),
        filename: '[name].bundle.js',
        sourceMapFilename: '[name].map',
        chunkFilename: '[id].chunk.js'
    },

    // Include configuration
    resolve: {
        extensions: ['', '.ts', '.js', '.css', '.html']
    },

    // Module configuration
    module: {
        preLoaders: [
            // Lint all TypeScript files
            {test: /\.ts$/, loader: 'tslint-loader'}
        ],
        loaders: [
            // Include all TypeScript files
            {test: /\.ts$/, loader: 'ts-loader'},

            // Include all HTML files
            {test: /\.html$/, loader: 'raw-loader'},

            // Include all CSS files
            {test: /\.css$/, loader: 'raw-loader'},
        ]
    },

    // Plugin configuration
    plugins: [
        // Bundle all third party libraries
        new CommonsChunkPlugin({name: 'vendor', filename: 'vendor.bundle.js', minChunks: Infinity}),

        // Uglify all bundles
        new UglifyJsPlugin({compress: {warnings: false}}),
    ],

    // Linter configuration
    tslint: {
        emitErrors: false,
        failOnHint: false
    }
};

// Helper functions
function root(args) {
    args = Array.prototype.slice.call(arguments, 0);
    return path.join.apply(path, [__dirname].concat(args));
}

vantaggi:

  • Linea di costruzione completa (linting TS, compilazione, minimizzazione, ecc.)
  • 3 file per la distribuzione -> Solo alcune richieste HTTP

svantaggi:

  • Tempo di costruzione superiore
  • Non è la soluzione migliore per i progetti Http 2 (vedi disclaimer)

Dichiarazione di non responsabilità: questa è una buona soluzione per Http 1. *, poiché riduce al minimo il sovraccarico per ogni richiesta Http. Hai solo una richiesta per il tuo index.html e per ogni pacchetto, ma non per 100-200 file. Al momento, questa è la strada da percorrere.

Http 2, d'altra parte, cerca di ridurre al minimo l'overhead Http, quindi si basa su un protocollo di flusso. Questo flusso è in grado di comunicare in entrambe le direzioni (Client <--> Server) e, per questo motivo, è possibile un caricamento delle risorse più intelligente (si caricano solo i file richiesti). Il flusso elimina gran parte dell'overhead Http (meno round trip Http).

Ma è lo stesso di IPv6: ci vorranno alcuni anni prima che le persone usino davvero Http 2


1
Non è necessario però, poiché l'OP ha menzionato l'uso angular-cliche già include un bundler (lo stesso webpack suggerito).
Mattarau,

2
@mdentinho Sì, in versioni più moderne. Ma nel 2016 SystemJS e CLI sono stati la strada da percorrere (Volentieri abbiamo webpack ora)
swaechter

21

Devi assicurarti di distribuire la cartella dist (abbreviazione di distribuibile) dal tuo progetto generato dalla CLI angolare . Ciò consente allo strumento di prendere il codice sorgente e le sue dipendenze e darti solo ciò di cui hai bisogno per eseguire l'applicazione.

Detto questo, c'è / era un problema con la CLI angolare per quanto riguarda le build di produzione tramite `ng build --prod

Ieri (2 agosto 2016) è stata rilasciata una versione che ha cambiato il meccanismo di costruzione da broccoli + systemjs a webpack che gestisce con successo build di produzione.

Sulla base di questi passaggi:

ng new test-project
ng build --prod

Sto vedendo una distdimensione della cartella di 1,1 MB tra i 14 file elencati qui:

./app/index.js
./app/size-check.component.css
./app/size-check.component.html
./favicon.ico
./index.html
./main.js
./system-config.js
./tsconfig.json
./vendor/es6-shim/es6-shim.js
./vendor/reflect-metadata/Reflect.js
./vendor/systemjs/dist/system.src.js
./vendor/zone.js/dist/zone.js

Nota Attualmente per installare la versione webpack del cli angolare, è necessario eseguire ...npm install angular-cli@webpack -g



12

Sembra che nessuno abbia menzionato la compilazione anticipata come descritto qui: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

La mia esperienza con Angular finora è che AoT crea le build più piccole senza quasi nessun tempo di caricamento. E, soprattutto, la domanda qui è: devi solo spedire alcuni file alla produzione.

Ciò sembra essere dovuto al fatto che il compilatore angolare non verrà distribuito con le build di produzione poiché i modelli vengono compilati "Ahead of Time". È anche molto bello vedere il markup del tuo modello HTML trasformato in istruzioni javascript che sarebbe molto difficile decodificare nell'HTML originale.

Ho realizzato un semplice video in cui dimostro dimensioni del download, numero di file, ecc. Per un'app Angular in sviluppo dev vs AoT - che puoi vedere qui:

https://youtu.be/ZoZDCgQwnmQ

Troverai il codice sorgente per la demo qui:

https://github.com/fintechneo/angular2-templates

E - come hanno detto tutti gli altri qui - non c'è niente di sbagliato quando ci sono molti file nel tuo ambiente di sviluppo. È così per tutte le dipendenze che derivano da Angular e da molti altri framework moderni. Ma la differenza qui è che quando si spedisce alla produzione dovresti essere in grado di comprimerlo in pochi file. Inoltre non vuoi tutti questi file di dipendenza nel tuo repository git.


8

Questo in realtà non è specifico angolare, succede con quasi tutti i progetti che utilizzano l'ecosistema NodeJs / npm per i suoi strumenti.

Tali progetti si trovano nelle cartelle node_modules e sono le dipendenze di transito necessarie per l'esecuzione delle dipendenze dirette.

Nel nodo ecosistema i moduli sono generalmente piccoli, il che significa che invece di sviluppare le cose noi stessi tendiamo a importare la maggior parte di ciò di cui abbiamo bisogno sotto forma di un modulo. Questo può includere cose così piccole come la famosa funzione pad sinistro, perché scriverlo noi stessi se non come esercizio?

Quindi avere molti file è davvero una buona cosa, significa che tutto è molto modulare e gli autori dei moduli hanno riutilizzato frequentemente altri moduli. Questa facilità di modularità è probabilmente uno dei motivi principali per cui l'ecosistema nodo è cresciuto così rapidamente.

In linea di principio, ciò non dovrebbe causare alcun problema, ma sembra che tu abbia un limite di conteggio dei file del motore delle app di Google. In tal caso, suggerisco di non caricare node_modules nel motore dell'app.

crea invece l'applicazione localmente e carica su Google App Engine solo i file in bundle, ma non sul motore di app integrato stesso.


8

Se si utilizza la versione più recente di angular cli, utilizzare ng build --prod

Si creerà dist cartella che hanno meno file e la velocità di progetto sarà aumentata.

Anche per i test in locale con le migliori prestazioni di cli angolari è possibile utilizzare ng serve --prod


6

se si utilizza l'interfaccia della riga di comando angolare è sempre possibile utilizzare l'opzione --minimal quando si crea un progetto

ng new name --minimal

L'ho appena eseguito con la bandiera e crea 24 600 file e ng build --prodproduce una cartella dist di 212 KB

Quindi se non hai bisogno di fontane d'acqua nel tuo progetto o vuoi semplicemente testare rapidamente qualcosa, penso che sia abbastanza utile


5

La creazione di un nuovo progetto con cli angolare di recente e la cartella node_modules era di 270 mb, quindi sì, questo è normale, ma sono sicuro che la maggior parte dei nuovi sviluppatori del mondo angolare lo mettono in discussione ed è valido. Per un semplice nuovo progetto sarebbe logico ridurre le dipendenze forse un po ';) Non sapere da cosa dipendono tutti i pacchetti può essere un po' snervante soprattutto per i nuovi sviluppatori che provano il cli per la prima volta. Aggiungi al fatto che la maggior parte dei tutorial di base non discute le impostazioni di distribuzione per ottenere solo i file esportati necessari. Non credo che nemmeno il tutorial offerto sul sito ufficiale angolare parli di come distribuire il semplice progetto.

Sembra che il colpevole sia la cartella node_modules


4

Ecco un confronto tra ciò che occupa più spazio nei progetti angolari. inserisci qui la descrizione dell'immagine


3

Se il tuo file system supporta i collegamenti simbolici, puoi almeno relegare tutti questi file in una cartella nascosta, in modo che uno strumento intelligente come treenon li visualizzi per impostazione predefinita.

mv node_modules .blergyblerp && ln -s .blergyblerp node_modules

L'uso di una cartella nascosta per questo può anche incoraggiare la comprensione che si tratta di file intermedi relativi alla build che non devono essere salvati nel controllo di revisione o utilizzati direttamente nella distribuzione.


Il mio pangrattato è diventato stantio, ma ecco a cosa si riferisce: web.archive.org/web/20150216184318/https://docs.npmjs.com/misc/…
nobar

2

Non c'è niente di sbagliato. Queste sono tutte le dipendenze dei nodi che hai citato in package.json.

Fai solo attenzione se hai scaricato parte del progetto git hub, potrebbe avere molte altre dipendenze che non sono effettivamente necessarie per la prima app angolare 2 ciao mondo :)

  • assicurati di avere dipendenze angolari -rxjs -gulp -typescript -tslint -docker
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.