未使用的带有providIn的可注入服务:'root'包含在main.js中,增加了包的大小(Angular 19,独立)

问题描述 投票:0回答:1

问题:

在 Angular 19 独立应用程序中,我有一个 API 客户端文件,其中包含 100 多个 @Injectable 服务,每个服务都标有

providedIn: 'root'
。然而,应用程序中仅使用了其中 3-4 个服务。问题是所有未使用的服务仍然包含在生产版本(main.js)中,从而显着增加了捆绑包的大小。

详情:

我正在使用完全独立的方法(Angular 19)构建一个新的 Angular 应用程序。我还有另一个使用 Angular 17 构建的应用程序,它遵循传统的基于 NgModule 的方法。两个应用程序都使用通过 NSwag Studio 生成的相同 API 客户端,它创建多个 @Injectable 服务,如下所示:

@Injectable({
    providedIn: 'root'
})
export class FeatureClient {}

在模块化应用程序(Angular 17)中: 未使用的服务被排除在最终捆绑包之外(tree-shaking 按预期工作)。 仅当显式注入时,使用的服务才会包含在 main.js 中。

在独立应用程序(Angular 19)中: 来自 API 客户端的所有服务都包含在 main.js 中,无论它们是使用还是注入。

从 API 客户端手动删除任何未使用的代码显然会减少包的大小。为了进一步验证这两个应用程序的情况,我执行了以下操作:

  1. 向 API 客户端文件添加模拟服务。
  2. 构建生产应用程序。
  3. 检查模拟服务是否存在于最终包(main.js)中。
  4. 将模拟服务注入组件中,重建并再次验证输出。

结果:

模块化应用程序: 如果未使用该服务,则该服务将从捆绑包中排除。 如果服务被注入,它会包含在main.js中。

独立应用程序: 无论注入如何,这两种情况都包含在内。

angular dependency-injection angular-cli tree-shaking angular-standalone-components
1个回答
0
投票

您可以执行此检查表来消除可能导致此问题的某些情况:

  1. 您创建的独立组件(使用这些服务)应该使用

    loadComponent
    -> 使用“loadComponent”延迟加载独立组件。急切加载的组件将被捆绑到
    main.js
    .

  2. 如果组件(使用这些服务)直接在 HTML 中加载,它们将导致服务被包含。您可以利用

    @defer
    确保仅当它们在视口中可见时才加载它们。还有大量其他加载选项,请参阅:使用@defer延迟加载

     @defer (on viewport) {
       <large-cmp />
     } @placeholder {
       <div>Large component placeholder</div>
     }
    
  3. 该服务不应该在初始默认页面中使用,例如:如果您的主页使用了5个服务。这些服务将被加载,因为它们是主页的依赖项。


如果您认为上述建议不适用于您,您应该创建一个最小的可重现 stackblitz 并在 Github Angular - Issues 上提出错误,以便 Angular 团队可以对此进行调查。提供的更多细节和工作示例将极大地帮助团队找到问题。

© www.soinside.com 2019 - 2024. All rights reserved.