Ogromna liczba plików wygenerowanych dla każdego projektu Angular


594

Chciałem uruchomić prostą aplikację hello world dla Angular.

Gdy wykonałem instrukcje z oficjalnego szybkiego startu, instalacja utworzyła 32 000 plików w moim projekcie.

Uznałem, że to jakaś pomyłka lub coś mi umknęło, więc zdecydowałem się użyć angular-cli , ale po skonfigurowaniu projektu naliczyłem 41 000 plików.

Gdzie popełniłem błąd? Czy brakuje mi czegoś naprawdę naprawdę oczywistego?


98
Jest to normalne w przypadku projektów opartych na NPM.
Everettss

115
@hendrix, ponieważ moje wdrożenie (silnik aplikacji Google) zezwala tylko na pliki 10 KB
Moshe Shaham

49
Dla każdego, kto jest ciekawy liczby głosów na to pytanie i odpowiedzi, jest to pierwsza strona HN. news.ycombinator.com/item?id=12209028
ceejayoz

50
@hendrix - Założę się, że zatwierdzasz również pliki .DS_Store do git.
Martin Konecny,

61
Myślę, że „Jeśli aplikacja Witaj na świecie działa, wszystko jest w porządku”, nie jest dobrą filozofią do naśladowania, szczególnie dla kogoś, kto się uczy. OP ma rację, pytając, dlaczego powstało tak wiele plików. Sam przykład odwołuje się tylko do 5 plików. I szczerze mówiąc, każda aplikacja, która ma więcej plików niż liter na wyjściu, powinna zostać zakwestionowana.
Shawn

Odpowiedzi:


362

W Twojej konfiguracji nie ma nic złego.

Angular (od wersji 2.0) używa modułów npm i zależności do programowania. To jedyny powód, dla którego widzisz tak ogromną liczbę plików.

Podstawowa konfiguracja Angulara zawiera transpiler, zależności typowania, które są niezbędne tylko do celów programistycznych.

Po zakończeniu programowania musisz jedynie spakować tę aplikację.

Po spakowaniu aplikacji będzie tylko jeden bundle.jsplik, który możesz następnie wdrożyć na serwerze.

„transpiler” to tylko kompilator, dziękuję @omninonsense za dodanie tego.


7
Zwykle przynosi również dane testowe i testy oraz buduje narzędzia dla zależności i ich zależności i tak dalej.
Benjamin Gruenbaum

63
„Transpiler” to tylko kompilator.
omninonsense

31
ale kompiluje się w innym języku zamiast bajtowego kodu lub kodu maszynowego
Hunter McMillen

32
@HunterMcMillen Kod bajtowy i / lub Kod maszynowy to inny język. Termin „transpiler” nie ma dodatkowego znaczenia niż „kompilator”.
Brandon Buck

76
W odniesieniu do wszystkich zaangażowanych nie jestem pewien, czy argument semantyki jest naprawdę istotny dla pytania OP ^^
Dan Pantry

144
                                Typical Angular2 Project

                       Pliki                   pakietu NPM (programowanie) Pliki świata rzeczywistego (wdrożenie)

@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

[ zobacz to dla procesu łączenia ⇗ ]


24
Sądzę, że -3podano, że nie zrobili sumy, ale teraz mam :)
Ankit Singh

1
co rozumiesz przez pliki świata rzeczywistego?
yeahman,

1
@yeahman „pliki świata rzeczywistego” to liczba plików, gdy projekt jest wdrażany lub produkowany .
Maarti,

Liczą się także rozmiary, tylko 3 pliki, ale mogą być ogromne (dla Internetu)
pdem

51

Nie ma nic złego w twojej konfiguracji programistycznej .

Coś jest nie tak z konfiguracją produkcyjną .

Kiedy tworzysz „Projekt Angular 2” lub „Dowolny projekt oparty na JS”, ​​możesz użyć wszystkich plików, możesz wypróbować wszystkie pliki, możesz zaimportować wszystkie pliki. Ale jeśli chcesz obsłużyć ten projekt, musisz połączyć wszystkie pliki strukturalne i pozbyć się niepotrzebnych plików.

Istnieje wiele opcji łączenia tych plików razem:


2
Nie powinieneś (potrzebne cytowanie) łączyć pliki razem na serwerze. Co najwyżej użyłbym transpilatora.
Dan Pantry

1
@DanPantry Transpilers to kompilatory typu źródło-źródło. Myślę, że mogą zmienić tylko „X” na „JS”. Liczba plików jest taka sama.
huragan

1
..Tak, ale nie jestem pewien, o co ci chodzi. Chodzi mi o to, że prawdopodobnie nie powinieneś próbować minimalizować kodu serwera (łącząc pliki, a tym samym zmniejszając rozmiar pliku). Co najwyżej powinieneś użyć Babel na swoim kodzie, jeśli używasz funkcji krwawienia, takich jak asynchronizacja / czekaj.
Dan Pantry

2
@ DanPantry Zgadzam się z tobą. Ale w komentarzach pytający mówi „ponieważ moje wdrożenie (silnik aplikacji Google) pozwala tylko na pliki 10K”. W tych warunkach musimy zminimalizować liczbę plików.
huragan

4
Zgadzam się z tobą, ale wydaje się, że OP ma problem z XY
Dan Pantry

30

Jak już wspomniano kilka osób: Wszystkie pliki w katalogu node_modules (lokalizacja NPM dla pakietów) są częścią zależności projektu (tzw. Zależności bezpośrednie). Dodatkowo, twoje zależności mogą również mieć swoje własne zależności itp. (Tzw. Zależności przechodnie). Kilka dziesięciu tysięcy plików to nic specjalnego.

Ponieważ możesz przesyłać tylko 10 000 plików (patrz komentarze), wybrałbym silnik pakujący. Ten silnik połączy wszystkie twoje JavaScript, CSS, HTML itp. I utworzy jeden pakiet (lub więcej, jeśli je określisz). Twój index.html załaduje ten pakiet i to wszystko.

Jestem fanem pakietu webpack, więc moje rozwiązanie webpack utworzy pakiet aplikacji i pakiet dostawcy (pełny działający program znajduje się tutaj https://github.com/swaechter/project-collection/tree/master/web-angular2- przykład ):

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));
}

Zalety:

  • Pełna linia kompilacji (kłaczkowanie, kompilacja, minimalizacja itp.)
  • 3 pliki do wdrożenia -> Tylko kilka żądań HTTP

Niedogodności:

  • Wyższy czas budowy
  • Nie najlepsze rozwiązanie dla projektów HTTP 2 (zobacz wyłączenie odpowiedzialności)

Oświadczenie: Jest to dobre rozwiązanie dla Http 1. *, ponieważ minimalizuje obciążenie ogólne dla każdego żądania HTTP. Masz tylko prośbę o indeks.html i każdy pakiet - ale nie o 100-200 plików. W tej chwili jest to właściwy sposób.

Z drugiej strony Http 2 próbuje zminimalizować narzut HTTP, więc jest oparty na protokole strumieniowym. Strumień ten może komunikować się w obu kierunkach (Klient <--> Serwer), dlatego możliwe jest bardziej inteligentne ładowanie zasobów (ładujesz tylko wymagane pliki). Strumień eliminuje znaczną część narzutu HTTP (mniej podróży w obie strony HTTP).

Ale to tak samo, jak w przypadku IPv6: minie kilka lat, zanim ludzie naprawdę zaczną korzystać z HTTP 2


1
Nie jest to jednak konieczne, ponieważ OP wspomniał o użyciu, angular-cliktóre już jest dostarczane z pakietem (ten sam sugerowany pakiet WWW).
mattarau,

2
@mdentinho Tak, w bardziej nowoczesnych wydaniach. Ale w 2016 roku SystemJS i CLI były już na dobrej drodze (cieszę się, że mamy teraz
webpack

21

Musisz upewnić się, że właśnie wdrażasz folder dist (skrót do dystrybucji) z twojego projektu wygenerowanego przez Angular CLI . Pozwala to narzędziu pobrać kod źródłowy i jego zależności i dać ci tylko to, czego potrzebujesz do uruchomienia aplikacji.

Biorąc to pod uwagę, istnieje / był problem z Angular CLI w odniesieniu do kompilacji produkcyjnych poprzez `ng build --prod

Wczoraj (02 sierpnia 2016) to wydanie zostało zrobione który włącza mechanizm zbudowany z brokułami + systemjs do WebPacka które z powodzeniem obsługuje produkcja buduje.

Na podstawie tych kroków:

ng new test-project
ng build --prod

Widzę distrozmiar folderu 1,1 MB w 14 wymienionych tutaj plikach :

./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

Uwaga Obecnie, aby zainstalować wersję kątową cli dla webpacka, musisz uruchomić ...npm install angular-cli@webpack -g



12

Wydaje się, że nikt nie wspomniał o Kompilacji Ahead-of-Time, jak opisano tutaj: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

Dotychczasowe doświadczenia z Angularem polegają na tym, że AoT tworzy najmniejsze kompilacje bez prawie żadnego czasu ładowania. I najważniejsze, ponieważ chodzi o pytanie - wystarczy wysłać tylko kilka plików do produkcji.

Wydaje się, że dzieje się tak, ponieważ kompilator Angular nie zostanie dostarczony z kompilacjami produkcyjnymi, ponieważ szablony są kompilowane „przed czasem”. Fajnie jest też widzieć znaczniki szablonów HTML przekształcone w instrukcje javascript, których odtworzenie w oryginalnym HTML byłoby bardzo trudne.

Nakręciłem prosty film, w którym pokazuję rozmiar pobierania, liczbę plików itp. Dla aplikacji Angular w wersji dev vs AoT - którą możesz zobaczyć tutaj:

https://youtu.be/ZoZDCgQwnmQ

Kod źródłowy wersji demo znajdziesz tutaj:

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

I - jak powiedzieli wszyscy inni tutaj - nie ma nic złego, gdy w twoim środowisku programistycznym jest wiele plików. Tak właśnie jest ze wszystkimi zależnościami, które występują w Angular i wielu innych współczesnych ramach. Różnica polega jednak na tym, że przy wysyłce do produkcji powinno być możliwe spakowanie jej do kilku plików. Nie chcesz też wszystkich tych plików zależności w repozytorium git.


8

W rzeczywistości nie jest to specyficzne dla Angulara, dzieje się tak w prawie każdym projekcie, który wykorzystuje ekosystem NodeJs / npm do swoich narzędzi.

Te projekty znajdują się w folderach node_modules i są zależnościami przejściowymi, które muszą być uruchomione przez bezpośrednie zależności.

W ekosystemie węzłów moduły są zwykle małe, co oznacza, że ​​zamiast sami opracowywać rzeczy, zwykle importujemy większość tego, czego potrzebujemy, w postaci modułu. Może to obejmować tak małe rzeczy, jak słynna funkcja lewego klawisza, po co pisać to sami, jeśli nie jako ćwiczenie?

Dlatego posiadanie dużej liczby plików jest dobrą rzeczą, oznacza to, że wszystko jest bardzo modułowe, a autorzy modułów często używali innych modułów. Ta łatwość modułowości jest prawdopodobnie jednym z głównych powodów, dla których ekosystem węzłów rozwijał się tak szybko.

Zasadniczo nie powinno to powodować żadnych problemów, ale wydaje się, że napotykasz limit liczby plików silnika aplikacji Google. W takim przypadku sugeruję, aby nie przesyłać node_modules do silnika aplikacji.

zamiast tego skompiluj aplikację lokalnie i prześlij do silnika aplikacji Google tylko dołączone pliki, ale nie do samego silnika aplikacji.


8

Jeśli używasz nowszej wersji angular cli, użyj ng build --prod

Stworzy folder dist, który ma mniej plików, a prędkość projektu wzrośnie.

Również do testowania lokalnego z najlepszą wydajnością kątowego cli, którego możesz użyć ng serve --prod


6

jeśli używasz Angular CLI, zawsze możesz użyć --minimal flagi podczas tworzenia projektu

ng new name --minimal

Właśnie uruchomiłem go z flagą i tworzy 24 600 plików i ng build --prodtworzy folder dist 212 KB

Jeśli więc nie potrzebujesz fontann na wodę w swoim projekcie lub po prostu chcesz szybko coś przetestować, myślę, że jest to bardzo przydatne


5

Tworzenie nowego projektu z kątowym cli ostatnio i folderem node_modules miał 270 mb, więc tak, jest to normalne, ale jestem pewien, że większość nowych programistów świata kątowego kwestionuje to i jest prawidłowe. W przypadku prostego nowego projektu sensowne może być nieco obniżenie zależności;) Niewiedza o tym, od czego zależą wszystkie pakiety, może być nieco denerwująca, szczególnie dla nowych deweloperów wypróbowujących cli po raz pierwszy. Dodaj do tego, że większość podstawowych samouczków nie omawia ustawień wdrażania, aby wyeksportowane pliki były potrzebne. Nie wierzę, że nawet samouczek oferowany na kanciastej oficjalnej stronie internetowej mówi o tym, jak wdrożyć prosty projekt.

Wygląda na to, że winowajcą jest folder node_modules



3

Jeśli twój system plików obsługuje dowiązania symboliczne, możesz przynajmniej przenieść wszystkie te pliki do ukrytego folderu - aby inteligentne narzędzie treenie wyświetlało ich domyślnie.

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

Użycie do tego ukrytego folderu może również zachęcić do zrozumienia, że ​​są to pliki pośrednie związane z kompilacją, które nie muszą być zapisywane w celu kontroli wersji - lub używane bezpośrednio we wdrożeniu.


Mój bułka tarta stała się nieaktualna, ale oto, do czego się odnosi: web.archive.org/web/20150216184318/https://docs.npmjs.com/misc/…
nobar

2

Nie ma w tym niczego złego. Są to wszystkie zależności węzłów wspomniane w pliku package.json.

Zachowaj ostrożność, jeśli pobrałeś część projektu git hub, może mieć wiele innych zależności, które nie są tak naprawdę wymagane dla aplikacji Angular 2 First Hello World :)

  • upewnij się, że masz zależności kątowe -rxjs -gulp -typescript -tslint -docker
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.