您的位置:首页 > Web前端 > AngularJS

[AngularJS2]AngularJS2应用启动过程

2017-12-08 12:39 218 查看
当浏览器访问Angular应用时,首先index.html页面被加载。

然后,inline.bundle.js被浏览器加载执行。在inline.bundle.js中定义了函数
webpackJsonp(...)
__webpack_require__(...)


通过函数
webpackJsonp(chunkIds, moreModules, executeModules)
可以向应用添加代码块,参数
chunkIds
是代码块的ID,
moreModules
是代码块中包含的模块,而
executeModules
指定了需要执行的模块。
webpackJsonp(...)
调用
__webpack_require__()
执行
executeModules
指定的模块。

/******/ (function(modules) { // webpackBootstrap
/******/     // install a JSONP callback for chunk loading
/******/     var parentJsonpFunction = window["webpackJsonp"];
/******/     window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
/******/
/******/         ... ...
/******/
/******/         if(executeModules) {
/******/             for(i=0; i < executeModules.length; i++) {
/******/                 result = __webpack_require__(__webpack_require__.s = executeModules[i]);
/******/             }
/******/         }
/******/         return result;
/******/     };
/******/
/******/     ... ...
/******/
/******/     // The require function
/******/     function __webpack_require__(moduleId) {
/******/
/******/         ... ...
/******/
/******/         // Execute the module function
/******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/         ... ...
/******/
/******/         // Return the exports of the module
/******/         return module.exports;
/******/     }
/******/
/******/ })
/******/ ([]);


当main.bundle.js被浏览器加载执行,函数
webpackJsonp(["main"], ..., [0])
会被调用执行。ID为“0”的模被块被执行,在执行中”../../../../../src/main.ts”模块也会被执行
__webpack_require__("../../../../../src/main.ts")


这里就是angular应用入口点:
platformBrowserDynamic().bootstrapModule(AppModule));


webpackJsonp(["main"],{

"../../../../../src/main.ts":

(function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n

var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__(\"../../../core/esm5/core.js\");
var __WEBPACK_IMPORTED_MODULE_1__angular_platform_browser_dynamic__ =
__webpack_require__(\"../../../platform-browser-dynamic/esm5/platform-browser-dynamic.js\");
var __WEBPACK_IMPORTED_MODULE_2__app_app_module__ = __webpack_require__(\"../../../../../src/app/app.module.ts\");

Object(__WEBPACK_IMPORTED_MODULE_1__angular_platform_browser_dynamic__[\"a\" /* platformBrowserDynamic */])()
.bootstrapModule(__WEBPACK_IMPORTED_MODULE_2__app_app_module__[\"a\" /* AppModule */]));

/***/ 0:
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__("../../../../webpack-dev-server/client/index.js?http://0.0.0.0:0");
module.exports = __webpack_require__("../../../../../src/main.ts");

/***/ })

},[0]);


platformBrowserDynamic
的定义可以在angular源代码packages\platform-browser-dynamic\src\platform-browser-dynamic.ts中找到。

export const platformBrowserDynamic = createPlatformFactory
( platformCoreDynamic, 'browserDynamic', INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS);


createPlatformFactory()
创建并返回对应的
PlatformRef
对象,
PlatformRef
是应用程序运行的环境。在packages\core\src\core\application_ref.ts中我们可以找到
PlatformRef
的定义。

export class PlatformRef {
private _modules: NgModuleRef<any>[] = [];
private _destroyListeners: Function[] = [];
private _destroyed: boolean = false;

bootstrapModule<M>(
moduleType: Type<M>, compilerOptions: (CompilerOptions&BootstrapOptions)|
Array<CompilerOptions&BootstrapOptions> = []): Promise<NgModuleRef<M>> {
const compilerFactory: CompilerFactory = this.injector.get(CompilerFactory);
const options = optionsReducer({}, compilerOptions);
const compiler = compilerFactory.createCompiler([options]);

return compiler.compileModuleAsync(moduleType)
.then((moduleFactory) => this.bootstrapModuleFactory(moduleFactory, options));
}
}


在BootstrapModule()
中,首先是模块被编译, 然后调用
BootstrapModuleFactory()
_moduleDoBootstrap()
。在
_moduleDoBootstrap()
中,我们可以看到对象
ApplicationRef
bootstrap()
方法被调用,参数是模块的每一Component。

const appRef = moduleRef.injector.get(ApplicationRef) as ApplicationRef;
if (moduleRef._bootstrapComponents.length > 0) {
moduleRef._bootstrapComponents.forEach(f => appRef.bootstrap(f));


ApplicationRef.bootstrap(componentOrFactory: ComponentFactory<C>|Type<C>, rootSelectorOrNode?: string|any)
的实现:

const selectorOrNode = rootSelectorOrNode || componentFactory.selector;
const compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);

compRef.onDestroy(() => { this._unloadComponent(compRef); });
const testability = compRef.injector.get(Testability, null);
if (testability) {
compRef.injector.get(TestabilityRegistry)
.registerApplication(compRef.location.nativeElement, testability);
}

this._loadComponent(compRef);


在这个函数里,
componentFactory
ComponentFactory_
对象的一个实例。
componentFactory.create()
的定义可以在packages\core\source\view\ref.ts中找到。

class ComponentFactory_ extends ComponentFactory<any>
/**
* Creates a new component.
*/
create(
injector: Injector, projectableNodes?: any[][], rootSelectorOrNode?: string|any,
ngModule?: NgModuleRef<any>): ComponentRef<any> {
if (!ngModule) {
throw new Error('ngModule should be provided');
}
const viewDef = resolveDefinition(this.viewDefFactory);
const componentNodeIndex = viewDef.nodes[0].element !.componentProvider !.nodeIndex;
const view = Services.createRootView(
injector, projectableNodes || [], rootSelectorOrNode, viewDef, ngModule, EMPTY_CONTEXT);
const component = asProviderData(view, componentNodeIndex).instance;
if (rootSelectorOrNode) {
view.renderer.setAttribute(asElementData(view, 0).renderElement, 'ng-version', VERSION.full);
}

return new ComponentRef_(view, new ViewRef_(view), component);
}
}


core\src\view\view.ts: function createRootView()->core\src\view\services.ts: function createProdRootView()->function createRootData()/function createRootView()

export function createRootView(root: RootData, def: ViewDefinition, context?: any): ViewData {
const view = createView(root, root.renderer, null, null, def);
initView(view, context, context);
createViewNodes(view);
return view;
}


createViewNode()会遍历view.def.nodes。如果node的类型是NodeFlags.TypeElement,createElement()会被调用在DOM树上创建节点,如果这个节点还是一个component, componentView也会被创建。

最后,调用execComponentViewsAction(view, ViewAction.CreateViewNodes),如果子节点是componentView, 递归的调用callViewAction()-> createViewNodes()来创建子节点,直到没有子节点是component.

function createViewNodes(view: ViewData) {
let renderHost: any;
if (isComponentView(view)) {
const hostDef = view.parentNodeDef;
renderHost = asElementData(view.parent !, hostDef !.parent !.nodeIndex).renderElement;
}
const def = view.def;
const nodes = view.nodes;
for (let i = 0; i < def.nodes.length; i++) {
const nodeDef = def.nodes[i];
Services.setCurrentNode(view, i);
let nodeData: any;
switch (nodeDef.flags & NodeFlags.Types) {
case NodeFlags.TypeElement:
const el = createElement(view, renderHost, nodeDef) as any;
let componentView: ViewData = undefined !;
if (nodeDef.flags & NodeFlags.ComponentView) {
const compViewDef = resolveDefinition(nodeDef.element !.componentView !);
componentView = Services.createComponentView(view, nodeDef, compViewDef, el);
}
listenToElementOutputs(view, componentView, nodeDef, el);
nodeData = <ElementData>{
renderElement: el,
componentView,
viewContainer: null,
template: nodeDef.element !.template ? createTemplateData(view, nodeDef) : undefined
};
if (nodeDef.flags & NodeFlags.EmbeddedViews) {
nodeData.viewContainer = createViewContainerData(view, nodeDef, nodeData);
}

nodes[i] = nodeData;
}
// Create the ViewData.nodes of component views after we created everything else,
// so that e.g. ng-content works
execComponentViewsAction(view, ViewAction.CreateViewNodes);

export function createElement(view: ViewData, renderHost: any, def: NodeDef): ElementData {
const elDef = def.element !;
const rootSelectorOrNode = view.root.selectorOrNode;
const renderer = view.renderer;
let el: any;
if (view.parent || !rootSelectorOrNode) {
if (elDef.name) {
el = renderer.createElement(elDef.name, elDef.ns);
} else {
el = renderer.createComment('');
}
const parentEl = getParentRenderElement(view, renderHost, def);
if (parentEl) {
renderer.appendChild(parentEl, el);
}
} else {
el = renderer.selectRootElement(rootSelectorOrNode);
}
if (elDef.attrs) {
for (let i = 0; i < elDef.attrs.length; i++) {
const [ns, name, value] = elDef.attrs[i];
renderer.setAttribute(el, name, value, ns);
}
}
return el;
}

export function createComponentView(
parentView: ViewData, nodeDef: NodeDef, viewDef: ViewDefinition, hostElement: any): ViewData {
const rendererType = nodeDef.element !.componentRendererType;
let compRenderer: Renderer2;
if (!rendererType) {
compRenderer = parentView.root.renderer;
} else {
compRenderer = parentView.root.rendererFactory.createRenderer(hostElement, rendererType);
}
return createView(
parentView.root, compRenderer, parentView, nodeDef.element !.componentProvider, viewDef);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息