[AngularJS2]AngularJS2应用启动过程
2017-12-08 12:39
218 查看
当浏览器访问Angular应用时,首先index.html页面被加载。
然后,inline.bundle.js被浏览器加载执行。在inline.bundle.js中定义了函数
通过函数
当main.bundle.js被浏览器加载执行,函数
这里就是angular应用入口点:
在这个函数里,
core\src\view\view.ts: function createRootView()->core\src\view\services.ts: function createProdRootView()->function createRootData()/function createRootView()
createViewNode()会遍历view.def.nodes。如果node的类型是NodeFlags.TypeElement,createElement()会被调用在DOM树上创建节点,如果这个节点还是一个component, componentView也会被创建。
最后,调用execComponentViewsAction(view, ViewAction.CreateViewNodes),如果子节点是componentView, 递归的调用callViewAction()-> createViewNodes()来创建子节点,直到没有子节点是component.
然后,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); }
相关文章推荐
- AngularJS应用的启动和执行过程
- AngularJS的启动过程分析
- 探究APP应用启动过程
- 架构设计三之app应用的启动过程分析
- AngularJS进阶(三十九)基于项目实例解析ng启动加载过程
- AngularJS的启动引导过程
- IOS应用启动过程
- Angularjs的启动过程分析
- Android应用启动过程
- AngularJS进阶(三十九)基于项目实战解析ng启动加载过程
- 2-4 启动Angular应用的过程
- android应用的启动过程
- android学习--Activity及应用启动过程
- AngularJS的启动引导过程
- 应用窗口activity的启动过程
- 2-4 启动Angular应用的过程
- cocos2d-x_Android应用启动调用过程简析
- Android成长之路之应用启动过程
- 安卓 应用app启动过程
- Android开发环境搭建和项目各文件介绍应用安装和启动过程