关于javascript:为每个Angular项目生成大量文件

Huge number of files generated for every Angular project

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

当我按照官方QuickStart中的说明操作时,安装程序在我的项目中创建了32000个文件。

我觉得这是个错误,或者我遗漏了一些东西,所以我决定使用angular cli,但是在设置项目之后,我计算了41000个文件。

我哪里出错了?我是否错过了一些非常明显的东西?


您的配置没有问题。

Angular(自2.0版以来)使用NPM模块和依赖项进行开发。这就是你看到这么多文件的唯一原因。

角度的基本设置包含蒸腾器、排版依赖项,这些依赖项仅对开发目的是必要的。

一旦完成了开发,您所需要做的就是捆绑这个应用程序。

绑定应用程序后,只有一个bundle.js文件可以部署到服务器上。

"蒸腾者"只是一个编译器,谢谢@omninusse添加它。


1
                                Typical Angular2 Project

NPM包文件(开发)真实世界文件(部署)

1
2
3
4
5
6
7
8
9
10
@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

[捆绑过程见此&nerr;]


您的开发配置没有任何问题。

生产配置有问题。

当你开发一个"Angular2项目"或者"任何基于JS的项目"时,你可以使用所有的文件,你可以尝试所有的文件,你可以导入所有的文件。但是如果你想为这个项目服务,你需要把所有的结构化文件合并起来,去掉无用的文件。

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

  • 压缩工具
  • Google关闭编译器
  • 对于服务器端(我认为最好)喝


正如一些人已经提到的:节点模块目录(包的NPM位置)中的所有文件都是项目依赖项(所谓的直接依赖项)的一部分。除此之外,您的依赖项还可以有自己的依赖项等等(所谓的可传递依赖项)。数万份档案没什么特别的。

因为你只允许上传10000个文件(见评论),我会使用Bundler引擎。这个引擎将捆绑您的所有javascript、css、html等,并创建一个捆绑包(如果您指定的话,可以创建更多)。index.html将加载这个包,就这样。

我是Webpack的粉丝,因此我的Webpack解决方案将创建一个应用程序包和一个供应商包(有关完整工作的应用程序,请参阅以下网址:https://github.com/swaechter/project collection/tree/master/web-angular2-example):

index.html文件

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
<head>
    <base href="/">
    Webcms
</head>
<body>
<webcms-application>Applikation wird geladen, bitte warten...</webcms-application>
<script type="text/javascript" src="vendor.bundle.js">
<script type="text/javascript" src="main.bundle.js">
</body>
</html>

web包.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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-linting、编译、缩小等)
  • 3个部署文件——>只有几个HTTP请求

缺点:

  • 更高的构建时间
  • 不是HTTP 2项目的最佳解决方案(请参见免责声明)

免责声明:这是一个很好的HTTP 1.*解决方案,因为它可以最大限度地减少每个HTTP请求的开销。您只对index.html和每个包有一个请求,但对100-200个文件没有。现在,这就是我们要走的路。

另一方面,HTTP2试图最小化HTTP开销,因此它基于流协议。此流能够双向通信(客户机<->服务器),因此可以进行更智能的资源加载(您只加载所需的文件)。流消除了大部分HTTP开销(减少了HTTP往返)。

但它与ipv6相同:人们需要几年时间才能真正使用HTTP 2


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

也就是说,Angular CLI在通过"ng build--prod"进行生产构建方面存在问题。

昨天(2016年8月2日)发布了一个版本,将构建机制从花椰菜+SystemJS转换为成功处理生产构建的Webpack。

基于这些步骤:

1
2
ng new test-project
ng build --prod

在这里列出的14个文件中,我看到一个1.1 MB的dist文件夹大小:

1
2
3
4
5
6
7
8
9
10
11
12
./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

注意:当前要安装Angular CLI的Webpack版本,必须运行…江户十一〔一〕号


Angular本身有很多依赖项,而且cli的beta版本下载的文件比以前多了四倍。

这是如何创建一个简单的项目将更少的文件("只有"10K文件)https://yakovfain.com/2016/05/06/starting-an-angular-2-rc-1-项目/


似乎没有人提前提到编译,如这里所述:https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

到目前为止,我对Angular的经验是,AOT创建的构建最小,几乎没有加载时间。最重要的是,这里的问题是-你只需要把一些文件发送到生产。

这似乎是因为角度编译器不会随生产版本一起提供,因为模板是"提前"编译的。看到您的HTML模板标记转换为JavaScript指令也很酷,这将很难逆向工程到原始HTML中。

我制作了一个简单的视频,演示了dev与aot构建中一个角度应用程序的下载大小、文件数量等,您可以在这里看到:

https://youtu.be/zozdcgqwnmq网站

您可以在这里找到演示的源代码:

https://github.com/fintechneo/angular2-模板

正如所有其他人在这里所说,当开发环境中有许多文件时,没有什么错。这就是它与角型框架以及许多其他现代框架的所有依赖关系的关系。但这里的区别在于,当运送到生产环境时,您应该能够将其打包到几个文件中。而且,您不希望所有这些依赖文件都在Git存储库中。


这实际上不是角度特定的,几乎所有使用nodejs/npm生态系统作为工具的项目都会发生这种情况。

这些项目位于节点模块文件夹中,是直接依赖项需要运行的传递依赖项。

在节点生态系统中,模块通常很小,这意味着我们倾向于以模块的形式导入我们需要的大部分内容,而不是自己开发东西。这可以包括像著名的左垫函数这样的小东西,如果不是作为练习,为什么要自己写呢?

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

原则上,这不应该引起任何问题,但您似乎遇到了谷歌应用程序引擎文件计数限制。在这种情况下,我建议不要将节点模块上传到应用程序引擎。

相反,在本地构建应用程序,并只将捆绑的文件n上传到Google应用程序引擎,而不上传到内置应用程序引擎本身。


如果您使用的是Angular CLI的较新版本,请使用ng build --prod

它将创建文件较少的dist文件夹,从而提高项目的速度。

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


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

1
ng new name --minimal

我刚刚用这个标志运行它,它创建了24600个文件,ng build --prod生成了212 kb的dist文件夹。

所以如果你的项目不需要饮水机,或者只是想快速测试一下,我认为这是非常有用的。


这里是一个角度项目中需要更多空间的比较。enter image description here


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

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

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


没什么问题。这些是您在package.json中提到的所有节点依赖项。

如果你已经下载了一些Git Hub项目,那么你就要小心了,它可能还有很多其他的依赖项,而这对于Angular2 FirstHelloWorld应用程序来说并不是必需的。

  • 确保你有角度依赖性RXJS狼吞虎咽-打字稿-特斯林特-码头工人