Grande número de arquivos gerados para cada projeto Angular


594

Eu queria iniciar um aplicativo simples olá mundo para Angular.

Quando segui as instruções no início rápido oficial, a instalação criou 32.000 arquivos no meu projeto.

Achei que fosse algum erro ou perdi alguma coisa, então decidi usar o angular-cli , mas depois de configurar o projeto, contei 41.000 arquivos.

Onde foi que eu errei? Estou sentindo falta de algo realmente muito óbvio?


98
É normal para projetos desenvolvidos pelo NPM.
Everettss 02/08/16

115
@hendrix porque meu implantação (google app engine) permite que apenas 10K arquivos
Moshe Shaham

49
Para qualquer pessoa curiosa sobre o número de votos nesta questão e suas respostas, isso foi destaque na primeira página do HN. news.ycombinator.com/item?id=12209028
ceejayoz

50
@ hendrix - Aposto que você também envia arquivos .DS_Store para o git.
Martin Konecny

61
Eu acho que "se o seu aplicativo hello world está funcionando, tudo está bem" não é uma boa filosofia a seguir, especialmente para alguém que está aprendendo. O OP está exatamente certo em questionar por que tantos arquivos foram criados. O próprio exemplo referencia apenas 5 arquivos. E, honestamente, qualquer aplicativo que tenha mais arquivos do que letras na saída deve ser questionado.
Shawn

Respostas:


362

Não há nada de errado com sua configuração.

Angular (desde a versão 2.0) usa módulos npm e dependências para desenvolvimento. Essa é a única razão pela qual você está vendo um número tão grande de arquivos.

Uma configuração básica do Angular contém transpiler, dependências de digitação que são essenciais apenas para fins de desenvolvimento.

Depois de concluir o desenvolvimento, tudo o que você precisará fazer é agrupar esse aplicativo.

Depois de agrupar seu aplicativo, haverá apenas um bundle.jsarquivo que você poderá implantar no servidor.

'transpiler' é apenas um compilador, obrigado @omninonsense por adicionar isso.


7
Ele também normalmente traz os dados e os testes de teste e constrói ferramentas para as dependências e suas dependências, etc.
Benjamin Gruenbaum

63
Um "transpiler" é apenas um compilador.
Omninonsense 02/08/16

32
mas compila para outro idioma em vez de código de bytes ou código de máquina
Hunter McMillen

32
@HunterMcMillen O código de bytes e / ou o código da máquina é outro idioma. O termo "transpiler" não tem significado adicional além de "compilador".
Brandon Buck

76
No que diz respeito a todos os envolvidos Eu não tenho certeza o argumento semântica é realmente relevante para a pergunta de OP ^^
Dan Pantry

144
                                Typical Angular2 Project

                       Arquivos de                   pacote NPM (desenvolvimento) Arquivos do mundo real (implantação)

@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

[ veja isso para processo de empacotamento ⇗ ]


24
Eu acho que -3foram dadas para não fazer a soma, mas agora eu tenho :)
Ankit Singh

1
o que você quer dizer com arquivos do mundo real?
yeahman

1
@yeahman "arquivos do mundo real" é o número de arquivos quando o seu projeto é implantado ou em produção .
Maarti 19/10/19

Também a contagem de tamanho, apenas 3 arquivos, mas eles podem ser enormes (para web)
pdem 30/01

51

Não há nada de errado com sua configuração de desenvolvimento .

Algo errado com sua configuração de produção .

Ao desenvolver um "Projeto Angular 2" ou "Qualquer projeto baseado em JS", você pode usar todos os arquivos, experimentar todos os arquivos, importar todos os arquivos. Mas se você deseja servir esse projeto, precisa COMBINAR todos os arquivos estruturados e se livrar de arquivos inúteis.

Existem muitas opções para combinar esses arquivos:


2
Você não deve (citação necessário) concatenar arquivos juntos no servidor. No máximo, eu usaria um transpiler.
Dan Pantry

1
Os transpiladores @DanPantry são compiladores de origem a fonte. Eu acho que eles só podem mudar "X" para "JS". As contagens de arquivos são iguais.
furacão

1
..Sim, mas não tenho certeza do seu ponto. O que quero dizer é que você provavelmente não deve tentar reduzir o código do servidor (concatenando arquivos e, assim, reduzindo o tamanho do arquivo). No máximo, você deve usar o Babel no seu código se estiver usando recursos de sangramento como async / waitit.
Dan Pantry

2
@ DanPantry Estou de acordo com você. Mas nos comentários o questionador diz "porque minha implantação (google app engine) permite apenas 10 mil arquivos". Nessas condições, precisamos minimizar as contagens de arquivos.
furacão

4
Eu concordo com você, mas OP parece ter um problema XY aqui
Dan Pantry

30

Como várias pessoas já mencionaram: Todos os arquivos no diretório node_modules (local do NPM para pacotes) fazem parte das dependências do seu projeto (chamadas dependências diretas). Além disso, suas dependências também podem ter suas próprias dependências, etc. (chamadas dependências transitivas). Vários dez mil arquivos não são nada de especiais.

Como você só pode carregar 10.000 arquivos (ver comentários), eu usaria um mecanismo de empacotador. Esse mecanismo agrupará todo o seu JavaScript, CSS, HTML etc. e criará um único bundle (ou mais, se você os especificar). Seu index.html carregará esse pacote e é isso.

Como sou fã do webpack, minha solução criará um pacote de aplicativos e um pacote de fornecedores (para o aplicativo de trabalho completo, veja aqui https://github.com/swaechter/project-collection/tree/master/web-angular2- exemplo ):

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

Vantagens:

  • Linha de construção completa (TS linting, compilação, minificação, etc.)
  • 3 arquivos para implantação -> Apenas algumas solicitações Http

Desvantagens:

  • Maior tempo de construção
  • Não é a melhor solução para projetos Http 2 (consulte o aviso)

Aviso Legal: Esta é uma boa solução para o Http 1. *, porque minimiza a sobrecarga de cada solicitação de Http. Você só tem uma solicitação para o seu index.html e cada pacote configurável - mas não para 100 - 200 arquivos. No momento, este é o caminho a percorrer.

O HTTP 2, por outro lado, tenta minimizar a sobrecarga do HTTP, por isso é baseado em um protocolo de fluxo. Esse fluxo é capaz de se comunicar nas duas direções (Cliente <--> Servidor) e, por isso, é possível um carregamento de recursos mais inteligente (você carrega apenas os arquivos necessários). O fluxo elimina grande parte da sobrecarga Http (menos viagens de ida e volta Http).

Mas é o mesmo que com o IPv6: levará alguns anos até que as pessoas realmente usem o Http 2


1
Porém, não é necessário, pois o OP mencionou o uso do angular-clique já vem com um empacotador (o mesmo webpack sugerido).
mattarau

2
@mdentinho Sim, em lançamentos mais modernos. Mas em 2016 o SystemJS e a CLI foram o caminho a seguir (felizmente, temos o webpack agora) #
swaechter

21

Você precisa garantir que está apenas implantando a pasta dist (abreviação de distribuível) do seu projeto gerado pela CLI Angular . Isso permite que a ferramenta pegue seu código-fonte e suas dependências e só lhe dê o que você precisa para executar seu aplicativo.

Dito isto, há / houve um problema com a CLI Angular em relação às compilações de produção via `ng build --prod

Ontem (2 de agosto de 2016), foi realizada uma liberação que mudou o mecanismo de compilação de broccoli + systemjs para webpack, que gerencia com êxito as compilações de produção.

Com base nestas etapas:

ng new test-project
ng build --prod

Estou vendo um disttamanho de pasta de 1,1 MB nos 14 arquivos listados aqui:

./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 Atualmente, para instalar a versão webpack do angular cli, você deve executar ...npm install angular-cli@webpack -g



12

Parece que ninguém mencionou a Compilação antecipada, como descrito aqui: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

Minha experiência com o Angular até agora é que o AoT cria as versões menores, quase sem tempo de carregamento. E o mais importante, como é a pergunta aqui - você só precisa enviar alguns arquivos para produção.

Isso ocorre porque o compilador Angular não será enviado com as compilações de produção, pois os modelos são compilados "Antecipadamente". Também é muito bacana ver sua marcação de modelo HTML transformada em instruções javascript que seriam muito difíceis de fazer a engenharia reversa no HTML original.

Fiz um vídeo simples em que demonstro o tamanho do download, o número de arquivos, etc., para um aplicativo Angular na compilação dev vs AoT - que você pode ver aqui:

https://youtu.be/ZoZDCgQwnmQ

Você encontrará o código fonte da demonstração aqui:

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

E - como todos os outros disseram aqui - não há nada errado quando há muitos arquivos em seu ambiente de desenvolvimento. É assim que acontece com todas as dependências que acompanham o Angular e com muitas outras estruturas modernas. Mas a diferença aqui é que, ao enviar para produção, você poderá compactá-lo em alguns arquivos. Além disso, você não deseja todos esses arquivos de dependência no seu repositório git.


8

Na verdade, isso não é específico da Angular, acontece com quase todos os projetos que usam o ecossistema NodeJs / npm para suas ferramentas.

Esses projetos estão dentro das pastas node_modules e são as dependências transititve que suas dependências diretas precisam executar.

No nó, os módulos do ecossistema são geralmente pequenos, o que significa que, em vez de desenvolvermos as coisas, tendemos a importar a maior parte do que precisamos sob a forma de um módulo. Isso pode incluir coisas pequenas, como a famosa função do teclado esquerdo, por que escrevê-la, se não como um exercício?

Portanto, ter muitos arquivos é realmente uma coisa boa, significa que tudo é muito modular e os autores de módulos frequentemente reutilizam outros módulos. Essa facilidade de modularidade é provavelmente uma das principais razões pelas quais o ecossistema de nós cresceu tão rápido.

Em princípio, isso não deve causar nenhum problema, mas parece que você se depara com um limite de contagem de arquivos do Google App Engine. Nesse caso, sugiro não fazer upload de node_modules para o App Engine.

em vez disso, crie o aplicativo localmente e faça o upload para o Google App Engine apenas os arquivos incluídos, mas não para a compilação no próprio App Engine.


8

Se você estiver usando a versão mais recente do angular cli, use ng build --prod

Isso criará dist pasta com menos arquivos e a velocidade do projeto aumentará.

Também para testes em locais com melhor desempenho do CLI angular, você pode usar ng serve --prod


6

se você usa a CLI angular, sempre pode usar a sinalização --minimal ao criar um projeto

ng new name --minimal

Acabei de executá-lo com o sinalizador e ele cria 24 600 arquivos e ng build --prodproduz uma pasta dist de 212 KB

Então, se você não precisa de fontes de água em seu projeto ou apenas deseja testar rapidamente algo, acho útil


5

Criar um novo projeto com o angular cli recentemente e a pasta node_modules tinha 270 mb, então sim, isso é normal, mas tenho certeza que a maioria dos novos desenvolvedores do mundo angular questiona isso e é válida. Para um novo projeto simples, faria sentido reduzir as dependências talvez um pouco;) Não saber do que todos os pacotes dependem pode ser um pouco irritante, especialmente para os novos desenvolvedores que tentam cli pela primeira vez. Acrescente o fato de que os tutoriais mais básicos não discutem as configurações de implantação para obter apenas os arquivos exportados. Não acredito que mesmo o tutorial oferecido no site oficial angular fale sobre como implantar o projeto simples.

Parece que a pasta node_modules é a culpada


4

Aqui está uma comparação do que ocupa mais espaço em projetos angulares. insira a descrição da imagem aqui


3

Se o seu sistema de arquivos suportar links simbólicos, você poderá pelo menos relegar todos esses arquivos para uma pasta oculta - para que uma ferramenta inteligente como essa treenão os exiba por padrão.

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

O uso de uma pasta oculta para isso também pode incentivar o entendimento de que esses são arquivos intermediários relacionados à construção que não precisam ser salvos no controle de revisão - ou usados ​​diretamente em sua implantação.


Minha trilha de navegação ficou obsoleta, mas aqui está o que se refere: web.archive.org/web/20150216184318/https://docs.npmjs.com/misc/…
nobar

2

Não há nada errado. Essas são todas as dependências do nó que você mencionou no package.json.

Apenas tenha cuidado se você tiver baixado parte do projeto git hub, ele pode ter muitas outras dependências que não são realmente necessárias para o aplicativo angular 2 first hello world :)

  • verifique se você possui dependências angulares -rxjs -gulp -typescript -tslint -docker
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.