【问题标题】:Huge number of files generated for every Angular project为每个 Angular 项目生成大量文件
【发布时间】:2017-07-01 08:29:45
【问题描述】:

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

当我按照官方quickstart 中的说明进行操作时,安装在我的项目中创建了 32,000 个文件。

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

我哪里做错了?我是否遗漏了一些非常明显的东西?

【问题讨论】:

  • 使用 NPM 的项目是正常的。
  • @hendrix 因为我的部署(谷歌应用引擎)只允许 10K 个文件
  • 对于任何对这个问题的投票数及其答案感到好奇的人,这使得 HN 成为头版。 news.ycombinator.com/item?id=12209028
  • @hendrix - 我打赌你也将 .DS_Store 文件提交到 git。
  • 我认为“如果你的 hello world 应用程序正常运行,一切都很好”不是一个很好的理念,尤其是对于正在学习的人。 OP完全正确地质疑为什么要创建这么多文件。该示例本身仅引用了 5 个文件。老实说,任何文件的输出多于字母的应用程序都应该受到质疑。

标签: javascript angular


【解决方案1】:

你的配置没有问题。

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

Angular 的基本设置包含转译器、类型化依赖项,这些必不可少仅用于开发目的。

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

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

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

【讨论】:

  • 它通常还会带来测试数据和测试以及依赖项及其依赖项的构建工具等。
  • “转译器”只是一个编译器。
  • 但编译成另一种语言而不是字节码或机器码
  • @HunterMcMillen 字节码和/或机器码是另一种语言。术语“转译器”除了“编译器”之外没有其他含义。
  • 对于所有相关人员,我不确定语义论点是否与 OP 的问题真正相关 ^^
【解决方案2】:
                                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

[see this for bundling process ⇗]

【讨论】:

  • 我猜 -3 是因为没有计算总和,但现在我有 :)
  • 真实世界的文件是什么意思?
  • @yeahman "real world files" 是您的项目部署生产中时的文件数。
  • 还有大小计数,只有 3 个文件,但它们可能很大(对于网络)
【解决方案3】:

您的开发配置没有问题。

您的生产配置有问题。

当您开发“Angular 2 项目”或“任何基于 JS 的项目”时,您可以使用所有文件,可以尝试所有文件,可以导入所有文件。但是如果你想为这个项目服务,你需要COMBINE所有的结构化文件并去掉无用的文件。

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

【讨论】:

  • 您不应该(需要引用)在服务器上将文件连接在一起。最多,我会使用转译器。
  • @DanPantry Transpilers 是源到源编译器。我认为他们只能将“X”更改为“JS”。文件数相同。
  • ..是的,但我不确定你的意思。我的观点是,您可能不应该尝试缩小服务器代码(通过连接文件从而减小文件大小)。如果你正在使用像 async/await 这样的出血特性,你最多应该在你的代码中使用 Babel。
  • @DanPantry 我同意你的看法。但是在 cmets 提问者说“因为我的部署(谷歌应用引擎)只允许 10K 文件”。在这些情况下,我们需要减少文件数。
  • 我同意你的看法,但 OP 似乎在这里有一个 XY 问题
【解决方案4】:

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

因为您只能上传 10'000 个文件(请参阅 cmets),所以我会使用捆绑程序引擎。该引擎将捆绑您所有的 JavaScript、CSS、HTML 等,并创建一个捆绑包(如果您指定它们,则可以创建更多包)。你的 index.html 将加载这个包,就是这样。

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

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 linting、编译、缩小等)
  • 3个部署文件-->只有几个Http请求

缺点:

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

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

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

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

【讨论】:

  • 虽然没有必要,因为 OP 提到使用 angular-cli 已经附带了一个捆绑器(相同的建议 webpack)。
  • @mdentinho 是的,在更现代的版本中。但是在 2016 年,SystemJS 和 CLI 是可行的方法(很高兴我们现在有了 webpack)
【解决方案5】:

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

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

昨天(2016 年 8 月 2 日)发布了一个版本,将构建机制从 broccoli + 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

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

【讨论】:

    【解决方案6】:

    Angular 本身有很多依赖项,而 CLI 的 beta 版本下载的文件要多四倍。

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

    【讨论】:

      【解决方案7】:

      最近使用 angular cli 创建了一个新项目,node_modules 文件夹为 270 mb,所以是的,这是正常的,但我敢肯定,大多数新开发人员对 angular 世界提出质疑,并且是有效的。对于一个简单的新项目,减少依赖关系可能是有意义的;)不知道所有包依赖什么可能有点令人不安,特别是对于第一次尝试 cli 的新开发人员来说。添加到大多数基本教程不讨论部署设置以获取仅需要的导出文件这一事实。我不相信即使是 angular 官方网站上提供的教程也不会谈论如何部署简单的项目。

      【讨论】:

        【解决方案8】:

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

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

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

        我制作了一个简单的视频,我在其中演示了开发与 AoT 构建中 Angular 应用程序的下载大小、文件数量等 - 你可以在这里看到:

        https://youtu.be/ZoZDCgQwnmQ

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

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

        而且 - 正如所有其他人所说的那样 - 当您的开发环境中有很多文件时没有什么问题。这就是 Angular 和许多其他现代框架附带的所有依赖项的情况。但这里的不同之处在于,在运送到生产环境时,您应该能够将其打包成几个文件。此外,您不希望 git 存储库中的所有这些依赖文件。

        【讨论】:

          【解决方案9】:

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

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

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

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

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

          而是在本地构建应用程序并仅将捆绑的文件上传到谷歌应用引擎,但不要上传到应用引擎本身的构建。

          【讨论】:

            【解决方案10】:

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

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

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

            【讨论】:

              【解决方案11】:

              如果你使用 Angular CLI,你总是可以在创建项目时使用 --minimal 标志

              ng new name --minimal
              

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

              因此,如果您的项目中不需要喷泉或只是想快速测试一些东西,我认为这非常有用

              【讨论】:

                【解决方案12】:

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

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

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

                【讨论】:

                【解决方案13】:

                没有错。这些就是你在 package.json 中提到的所有节点依赖。

                如果你下载了一些 git hub 项目,请小心,它可能有很多其他依赖项,这些依赖项实际上并不需要 angular 2 first hello world app :)

                • 确保你有角度依赖 -rxjs -gulp -打字稿 -tslint -码头工人

                【讨论】:

                  【解决方案14】:

                  你的开发配置没有问题。

                  如果你使用 Angular CLI,你总是可以在创建项目时使用 --minimal 标志

                  ng new name --minimal
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-03-26
                    • 2020-04-22
                    • 2021-07-22
                    • 2019-04-07
                    • 2021-12-30
                    • 2012-09-03
                    相关资源
                    最近更新 更多