Angular CLI配置为不按需加载脚本是否有原因?

时间:2016-12-16 09:11:23

标签: angular webpack angular-cli

我是Angular 2和模块加载器的新手。我正在使用Angular CLI构建我的项目。我了解到Webpack加载了应用程序所需的模块(树木抖动?)并将它们打包成一个或几个文件。我仍然对此与基于用户需求下载脚本文件感到困惑。完成后,我的Angular应用程序可能会有大约100个组件。采用默认的CLI方式并立即将所有组件交付给客户端是否明智?或者按需加载它们是否更好?

1 个答案:

答案 0 :(得分:2)

很抱歉答案很长,但问题似乎是我们需要先了解一些基础知识。

模块捆绑包

聪明的模块捆绑器将能够:

  • 静态分析您的导入(以及导入的导入等),以便进行树木抖动,排除从未导入的代码。

    仅当脚本用作模块时才有效。这就是为什么一个好的模块捆绑器会为你提供一种从这个操作中排除一些遗留脚本的方法。

    请注意,这不是uglification或最小化。 minifier / uglifier可能会根据对代码的理解删除看起来未使用的代码,但如果过多,可以删除一些实际使用的代码(例如,尝试按名称加载函数,其中名称是动态的)一个字符串.Minifier可能认为该函数从未使用过。)

    树摇动仅适用于导入,因为它们是静态的,不能是动态的。 SystemJS是一个可以使它们动态化的模块捆绑器,但这意味着在单独的请求中加载了大量额外的文件,从而导致用户的响应时间更长。

  • 正确优化文件总数,并以最佳方式为其提供服务

    也就是说,单个文件可以保存HTTP请求,并且加载速度很快,除非文件非常大并且浏览器没有被文件阻止并且可以加载多个文件。除了加载多个文件之外,还有其限制,因为浏览器不会并行化这么多文件。

    一个优秀的捆绑器会为您提供一些额外的功能,例如有关文件大小的统计信息,以及根据文件内容在文件名中生成唯一哈希值,以便在文件内容更改时,更改文件的URL始终不同。它也会将动态名称注入到HTML中。

  • 它会为你提供一种延迟加载模块的方法 - 这就是你所说的

    您比任何人都更了解您的应用程序。您对用户有一定的期望。您知道当应用程序加载并且没有时间加载时,应用程序的哪些部分可以更好地准备好,哪些只会使初始负载过大而实际上会对用户体验产生负面影响。

    一个好的捆绑器允许你指定哪些位来延迟加载",或者分成不同的文件,并在用户请求这些位时透明地为你加载该文件。

Webpack和Angular CLI

正如您可能已经猜到的那样,Webpack 2会执行我们所说的优秀捆绑程序应该执行的所有操作。它:

  • 以适当的捆绑脚本加载文件
  • 应用树状抖动,散列和最小化等优化
  • 允许从抖动或整个处理中排除文件
  • 将动态脚本名称注入HTML
  • 透明地处理延迟加载,在构建时生成多个包,并在运行时为您透明地加载包

事情是:所有这些(以及更多功能)都是可选的。他们中的许多需要插件(内置和第三方)和配置(例如,缩小了多远,将脚本注入的HTML文件,要在包中加载的文件,要使用的文件名格式等等等等。)。

您使用的Webpack功能越多,您的Webpack配置就越失控。

Angular CLI开始的地方。

它具有完美的默认值,并包含许多功能。它封装了用于添加这些功能的整个配置。

特定于您的问题的其中一项功能是延迟加载

延迟加载

你告诉Webpack延迟加载某些东西的方法是调用一个尚未被批准作为标准的API。它还允许其他方式与节点模块比标准EcmaScript模块更相似。

Angular Router允许您跳过此语法,并使用Angular Router特定语法延迟加载Angular模块(想想@NgModule({})而不是EcmaScript / Node模块)。

例如,延迟加载/admin模块,假设它看起来像这样:

@NgModule({
  imports: [CommonModule, ...],
  declarations: [ ... ],
  providers: [
    RouterModule.forChild([
      {path: '', component: AdminComponent }
    ]),
    ...
  ],
})
export class AdminModule {}

您可以更改AppModule的路线:

const Routes = [
  ...,
  { path: '/admin', loadChildren: () => AdminModule }
];

要:

const Routes = [
  ...,
  { path: '/admin', loadChildren: './admin/admin.module#AdminModule' }
];

然后你将离开Angular Router,Angular CLI和Webpack来发挥魔力。

请勿让您的import { AdminModule } from './admin/admin.module';行保持畅通,因为即使未使用AdminModule,此WiLL也会将模块加载到主应用程序包中。因为所述树摇动是一个静态过程,仅适用于EcmaScript导入分析。

附加功能。

Angular CLI将--routing参数添加到ng generate moduleng new命令,这些命令添加新文件,如admin-routing.module.tsapp-routing.module.ts文件,以分隔路由进入自己的档案。这很好,它也只是组织性的。

一个常见的错误是认为您需要引用AdminRoutesModule中的AppRoutesModule文件,这是错误的。不同的模块和额外的文件没有任何区别。

实施例

如果你想查看更多代码,我在这里有一个简单的存储库来查看:

https://github.com/meligy/routing-angular-cli

注意:

不幸的是,Angular CLI beta 24中的延迟加载被破坏了。它已跟踪here。我将根据问题中建议的解决方案查看是否可以处理拉取请求。