每个Angular项目生成大量文件


594

我想为Angular启动一个简单的hello world应用程序。

当我按照官方快速入门中的说明进行安装时,安装程​​序在我的项目中创建了32,000个文件。

我认为这是一个错误,或者我错过了一些东西,所以我决定使用angular-cli,但是在设置项目后,我计算了41,000个文件。

我哪里做错了?我是否错过了确实很明显的东西?


98
对于由NPM支持的项目,这是正常的。
Everettss

115
@hendrix,因为我的部署(Google App引擎)仅允许1万个文件
Moshe Shaham

49
对于任何对此问题及其答案的投票数量感到好奇的人,这都成为了HN的头版。news.ycombinator.com/item?id=12209028
ceejayoz

50
@hendrix-我敢打赌你也将.DS_Store文件提交到git。
Martin Konecny

61
我认为“如果您的hello world应用程序正常运行,那么一切都很好”不是遵循的好哲学,特别是对于正在学习的人。OP完全正确地质疑了为什么创建了这么多文件。该示例本身仅引用5个文件。老实说,任何文件大于其输出字母的应用程序都应受到质疑。
肖恩

Answers:


362

您的配置没有错。

Angular(从2.0版开始)使用npm模块和依赖项进行开发。这是您看到如此大量文件的唯一原因。

Angular的基本设置包含编译器,键入依赖项,这些依赖项仅对开发目的至关重要

开发完成后,您需要做的就是捆绑此应用程序。

捆绑应用程序后,将只有一个bundle.js文件,然后可以将其部署在服务器上。

'transpiler'只是一个编译器,谢谢@omninonsense的添加。


7
它还通常会带来测试数据,测试以及针对依赖项及其依赖项的构建工具等。
本杰明·格伦鲍姆

63
“编译器”只是一个编译器。
omn​​inonsense

31
但会编译为另一种语言,而不是字节码或机器码
Hunter McMillen's 2016年

32
@HunterMcMillen字节码和/或机器码是另一种语言。术语“编译器”除“编译器”外没有其他含义。
布兰登·巴克

76
对于所有相关人员,我不确定语义论点是否确实与OP的问题相关^^
Dan Pantry

144
                                Typical Angular2 Project

NPM软件包                       文件(开发)                   实际文件(部署)

@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

[ 有关捆绑过程,请参阅此内容⇗ ]


24
我猜-3是因为没有做和,但现在我有了:)
Ankit Singh

1
您所说的真实世界文件是什么意思?
yeahman

1
@yeahman “真实世界的文件”是项目部署投入生产时的文件数。
马尔蒂

大小也算在内,只有3个文件,但它们可能很大(对于Web)
pdem

51

您的开发配置没有错。

您的生产配置有问题。

当开发“ Angular 2项目”或“基于JS的任何项目”时,您可以使用所有文件,可以尝试所有文件,也可以导入所有文件。但是,如果要为该项目提供服务,则需要合并所有结构化文件并清除无用的文件。

有很多选项可以将这些文件组合在一起:


2
您不应该(需要引用)在服务器上将文件串联在一起。最多,我会使用编译器。
Dan Pantry'8

1
@DanPantry Transpilers是源到源编译器。我认为他们只能将“ X”更改为“ JS”。文件数相同。
飓风

1
..是的,但是我不确定你的意思。我的观点是,您可能不应该尝试最小化服务器代码(通过串联文件并因此减小文件大小)。如果您正在使用异步/等待之类的强大功能,则最多应在代码上使用Babel。
Dan Pantry'8

2
@ DanPantry我同意你的看法。但是在评论中,提问者说“因为我的部署(Google App引擎)仅允许1万个文件”。在这种情况下,我们需要减少文件数量。
飓风

4
我会同意您的意见,但OP在这里似乎存在XY问题
Dan Pantry,2016年

30

正如已经提到的几个人:node_modules目录中的所有文件(软件包的NPM位置)都是项目依赖项(所谓的直接依赖项)的一部分。除此之外,您的依存关系也可以具有自己的依存关系,依此类推(所谓的传递依存关系)。几万个文件没什么特别的。

因为只允许您上传10,000个文件(请参阅评论),所以我将使用捆绑器引擎。该引擎将捆绑您的所有JavaScript,CSS,HTML等,并创建一个捆绑(如果指定了捆绑,则更多)。您的index.html将加载此捆绑包,仅此而已。

我是webpack的狂热者,因此我的webpack解决方案将创建一个应用程序捆绑包和一个供应商捆绑包(有关完整的工作应用程序,请参见https://github.com/swaechter/project-collection/tree/master/web-angular2-示例):

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

优点:

  • 完整的生产线(TS整理,编译,缩小等)
  • 3个部署文件->仅几个Http请求

缺点:

  • 建造时间更长
  • 不是Http 2项目的最佳解决方案(请参阅免责声明)

免责声明:这对于Http 1. *是一个很好的解决方案,因为它可以最大程度地减少每个Http请求的开销。您只需要索取index.html和每个捆绑包-而不是100-200个文件。目前,这是要走的路。

另一方面,Http 2试图最小化Http开销,因此它基于流协议。此流可以双向通信(客户端<->服务器),因此,可以更智能地加载资源(仅加载所需的文件)。该流消除了许多Http开销(减少Http往返)。

但这与IPv6相同:直到人们真正使用Http 2还要花几年的时间


1
不过没有必要,因为提到的OP angular-cli已经使用了捆绑软件(建议使用相同的webpack)。
mattarau

2
@mdentinho是的,在更现代的发行版中。但是在2016年,要走SystemJS和CLI的路要走(很高兴我们现在有了webpack)
swaechter

21

您需要确保仅从Angular CLI生成的项目中部署dist(可分发的简称)文件夹。这允许该工具获取您的源代码及其依赖项,并且仅提供运行应用程序所需的内容。

话虽这么说,Angular CLI在通过ng build --prod进行生产构建方面存在问题

昨天(2016年8月2日)发布了一个版本,该版本将构建机制从西兰花 + systemjs切换可成功处理生产构建的webpack

基于以下步骤:

ng new test-project
ng build --prod

我在这里列出的14个文件中看到1.1 MBdist文件夹大小:

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

注意当前要安装角度cli的webpack版本,必须运行...npm install angular-cli@webpack -g



12

似乎没有人像此处所述提到过提前编译:https : //angular.io/docs/ts/latest/cookbook/aot-compiler.html

到目前为止,我对Angular的经验是AoT创建了最小的构建,几乎没有加载时间。最重要的是这里的问题-您只需要将几个文件发送到生产环境即可。

这似乎是因为Angular编译器不会随生产版本一起提供,因为模板是“提前”编译的。看到HTML模板标记转换为javascript指令(将其反向工程为原始HTML十分困难)也很酷。

我制作了一个简单的视频,演示了在开发vs AoT构建中Angular应用程序的下载大小,文件数等-您可以在此处查看:

https://youtu.be/ZoZDCgQwnmQ

您可以在此处找到该演示的源代码:

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

而且-正如所有其他所有人所说的-当您的开发环境中有许多文件时,这没有什么错。Angular和所有其他现代框架附带的所有依赖项就是这样。但是这里的区别在于,当运送到生产环境时,您应该能够将其打包成几个文件。另外,您也不想在git存储库中使用所有这些依赖文件。


8

这实际上不是特定于Angular的,它几乎发生在所有使用NodeJs / npm生态系统作为其工具的项目中。

这些项目位于node_modules文件夹中,并且是直接依赖项需要运行的transititve依赖项。

在节点中,生态系统模块通常很小,这意味着我们不自行开发东西,而是倾向于以模块的形式导入我们需要的大部分内容。这可能包括一些小事情,例如著名的左键盘功能,为什么不自己做练习就自己写呢?

因此拥有大量文件实际上是一件好事,这意味着一切都非常模块化,并且模块作者经常重用其他模块。这种模块化的简便性可能是节点生态系统如此快速增长的主要原因之一。

原则上,这应该不会引起任何问题,但似乎您遇到了Google App Engine文件数限制。在这种情况下,我建议不要将node_modules上传到应用引擎。

而是在本地构建应用程序,仅将捆绑的文件上传到google app引擎,而不上传到内置的应用程序引擎本身。


8

如果您正在使用angular cli的较新版本,请使用 ng build --prod

它将创建文件更少的dist文件夹,并提高项目速度。

也可以在本地使用最佳角度cli性能进行测试 ng serve --prod


6

如果使用Angular CLI,则在创建项目时始终可以使用--minimal标志

ng new name --minimal

我刚刚用标志运行它,它创建了24 600个文件并ng build --prod产生212 KB dist文件夹

因此,如果您不需要项目中的饮水机或只是想快速测试一下,我认为这很有用


5

最近使用angular cli创建一个新项目,并且node_modules文件夹为270 mb,所以是的,这是正常的,但是我敢肯定,大多数来自Angle World的新开发人员对此表示怀疑并且是有效的。对于一个简单的新项目,将依赖关系减少一些可能是有意义的;)不知道所有程序包所依赖的内容可能会有些不安,尤其是对于那些初次尝试淘汰的新开发人员而言。事实是,大多数基础教程都没有讨论仅需要获取导出文件的部署设置。我什至不相信甚至有角官方网站上提供的教程也不会谈论如何部署简单项目。

看起来是node_modules文件夹是罪魁祸首



3

如果您的文件系统支持符号链接,那么您至少可以将所有这些文件释放到一个隐藏的文件夹中-这样,tree默认情况下,像这样的智能工具就不会显示它们。

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

为此使用隐藏文件夹也可能有助于理解这些是与构建相关的中间文件,不需要保存到修订控制中或直接在部署中使用。


我的面包屑已经过时了,但是它所指的是: web.archive.org/web/20150216184318/https
//docs.npmjs.com/misc/…– nobar

2

没有任何错误。这些都是您在package.json中提到的所有节点依赖项。

请注意,如果您下载了一些git hub项目,它可能还有很多其他依赖,而Angular 2 first hello world应用实际上并不需要这些依赖:)

  • 确保您具有角度依赖性-rxjs -gulp -typescript -tslint -docker
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.