在 Angular 中引导应用程序
介绍
加载 index.html 页面、应用级模块和应用级组件的过程称为引导,或加载应用。在本指南中,您将了解引导过程的内部原理。
Angular 采用以下步骤来引导应用程序:
- 加载 index.html
- 加载 Angular、其他库和应用代码
- 执行 main.ts 文件
- 加载应用程序级模块
- 加载应用级组件
- 流程模板
加载 index.html
任何 Angular Web 应用程序的起点都是 index.html 页面。此页面引用应用程序所需的所有 JavaScript 文件。如果您在构建 Angular 项目后检查 index.html 文件,您会发现它引用了 JavaScript 文件,如下所示:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GettingStarted</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script src="runtime-es2015.js" type="module"></script>
<script src="runtime-es5.js" nomodule defer></script>
<script src="polyfills-es5.js" nomodule defer></script>
<script src="polyfills-es2015.js" type="module"></script>
<script src="styles-es2015.js" type="module"></script>
<script src="styles-es5.js" nomodule defer></script>
<script src="vendor-es2015.js" type="module"></script>
<script src="vendor-es5.js" nomodule defer></script>
<script src="main-es2015.js" type="module"></script>
<script src="main-es5.js" nomodule defer></script></body>
</html>
您会注意到每个文件都有两个版本:
- es2015
- es5
main.js中包含应用程序代码。
执行main.js代码
main.js文件中的代码是应用程序的入口点。此文件从库@angular/platform-browser-dynamic导入模块platformBrowserDynamic。platformBrowserDynamic是负责在桌面浏览器中加载 Angular 应用程序的模块。与此模块类似,模块platformNativeScriptDynamic可在移动设备中加载应用程序。Angular 足够灵活,可以在浏览器、服务器、Web 工作器或移动设备中运行。
当调用bootstrapModule(AppModule, options)时,它会在第一步编译AppModule 。
bootstrapModule函数的代码如下:
bootstrapModule<M>(moduleType: Type<M>, options: CompilerOptions): Promise<NgModuleRef<M>> {
return compileNgModuleFactory(this.injector, options, moduleType)
.then((moduleFactory: NgModuleFactory) => {
// ...
});
}
您会注意到bootstrapModule正在调用compileNgModuleFactory,它具有以下代码:
function compileNgModuleFactory<M>(
injector: Injector,
options: CompilerOptions,
moduleType: Type<M>
): Promise<NgModuleFactory<M>> {
const compilerFactory: CompilerFactory = injector.get(CompilerFactory);
const compiler = compilerFactory.createCompiler([options]);
return compiler.compileModuleAsync(moduleType);
}
首先,它从注入器中检索CompilerFactory的实例。CompilerFactory是一个抽象类,负责创建编译器的实例。如果 Angular 应用在开发模式下运行,则会创建一个JitCompiler实例,其代码如下:
export class JitCompiler {
private compileModuleAsync(moduleType: Type): Promise<NgModuleFactory> {
return this._loadModules(moduleType)
.then(() => {
this._compileComponents(moduleType);
return this._compileModule(moduleType);
});
}
}
您会注意到它正在加载所有模块、指令和管道元数据。然后,它会编译所有组件。在组件编译期间,它会搜索应用程序中注册的所有组件元数据,并要求编译器在一个地方编译所有组件模板。它做的最后一件事是实际编译应用程序级模块。在此阶段,Angular 解析模块所需的所有元数据并返回模块工厂。
在引导 Angular 应用之前,platformBrowserDynamic需要创建一个根NgZone。根NgZone必须在创建AppModule之前实例化,因为所有应用逻辑都必须包装在根区域内。
当根NgZone创建完成后,platformBrowserDynamic通过模块编译步骤创建的根模块工厂实例化应用程序级模块。
每个 Angular 应用至少有一个模块。应用加载时最先加载的模块称为应用级模块或根模块。platformBrowserDynamic通过调用bootstrapModule函数并向其提供对应用级模块(即AppModule )的引用来引导应用级模块。
加载应用程序级模块
应用程序级模块或根模块有一个应用程序级组件或根组件。当 Angular 加载应用程序级模块时,会加载此应用程序级组件或根组件。除了应用程序级组件之外,此模块还引用使用 imports 数组导入的所有外部模块。该模块还引用了需要作为单例加载并可在整个应用程序中使用的所有服务。
NgModule装饰器的bootstrap属性或键指定在应用级模块加载时 Angular 应该加载哪个组件。Angular 会读取 bootstrap 元数据并加载应用级组件(称为AppComponent )。
加载应用级组件
应用程序级组件的 TypeScript 类名为AppComponent ,由@Component类装饰器装饰。@Component类装饰器向 Angular 提供有关该类的元数据。 它具有以下三个属性:
- 选择器
- 模板URL
- 样式网址
如果您要将服务注入此组件,那么您还将拥有第四个属性,该属性引用将注入此类构造函数的服务。第四个属性称为提供程序。它是将注入此组件的服务类的数组。
流程模板
templateURL属性指向 HTML 模板文件,在处理此组件时,该文件将被呈现给浏览器。selector属性指定CSS 选择器,模板将插入到 HTML 中。
一旦platformBrowserDynamic完成所有准备,它就可以实例化应用程序级组件或根组件。platformBrowserDynamic然后只需遍历引导组件数组并要求ApplicationRef实际引导每个组件。
结论
恭喜!您已经了解了 Angular 引导过程的内部原理。有关更多信息,请参阅Angular 中的引导。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~