Angular应用bootstrap时的version检测机制

122 阅读1分钟

core.js里:

 create(injector, projectableNodes, rootSelectorOrNode, ngModule) {
        ngModule = ngModule || this.ngModule;
        /** @type {?} */
        const rootViewInjector = ngModule ? createChainedInjector(injector, ngModule.injector) : injector;
        /** @type {?} */
        const rendererFactory = (/** @type {?} */ (rootViewInjector.get(RendererFactory2, domRendererFactory3)));
        /** @type {?} */
        const sanitizer = rootViewInjector.get(Sanitizer, null);
        /** @type {?} */
        const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
        // Determine a tag name used for creating host elements when this component is created
        // dynamically. Default to 'div' if this component did not specify any tag name in its selector.
        /** @type {?} */
        const elementName = (/** @type {?} */ (this.componentDef.selectors[0][0])) || 'div';
        /** @type {?} */
        const hostRNode = rootSelectorOrNode ?
            locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation) :
            elementCreate(elementName, rendererFactory.createRenderer(null, this.componentDef), getNamespace$1(elementName));
        /** @type {?} */
        const rootFlags = this.componentDef.onPush ? 64 /* Dirty */ | 512 /* IsRoot */ :
            16 /* CheckAlways */ | 512 /* IsRoot */;
        // Check whether this Component needs to be isolated from other components, i.e. whether it
        // should be placed into its own (empty) root context or existing root context should be used.
        // Note: this is internal-only convention and might change in the future, so it should not be
        // relied upon externally.
        /** @type {?} */
        const isIsolated = typeof rootSelectorOrNode === 'string' &&
            /^#root-ng-internal-isolated-\d+/.test(rootSelectorOrNode);
        /** @type {?} */
        const rootContext = createRootContext();
        // Create the root view. Uses empty TView and ContentTemplate.
        /** @type {?} */
        const rootTView = createTView(0 /* Root */, -1, null, 1, 0, null, null, null, null, null);
        /** @type {?} */
        const rootLView = createLView(null, rootTView, rootContext, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector);
        // rootView is the parent when bootstrapping
        // TODO(misko): it looks like we are entering view here but we don't really need to as
        // `renderView` does that. However as the code is written it is needed because
        // `createRootComponentView` and `createRootComponent` both read global state. Fixing those
        // issues would allow us to drop this.
        enterView(rootLView, null);
        /** @type {?} */
        let component;
        /** @type {?} */
        let tElementNode;
        try {
            /** @type {?} */
            const componentView = createRootComponentView(hostRNode, this.componentDef, rootLView, rendererFactory, hostRenderer);
            if (hostRNode) {
                if (rootSelectorOrNode) {
                    setUpAttributes(hostRenderer, hostRNode, ['ng-version', VERSION.full]);
                }
                else {
                    // If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
                    // is not defined), also apply attributes and classes extracted from component selector.
                    // Extract attributes and classes from the first selector only to match VE behavior.
                    const { attrs, classes } = extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]);
                    if (attrs) {
                        setUpAttributes(hostRenderer, hostRNode, attrs);
                    }
                    if (classes && classes.length > 0) {
                        writeDirectClass(hostRenderer, hostRNode, classes.join(' '));
                    }
                }
            }
            tElementNode = (/** @type {?} */ (getTNode(rootTView, 0)));
            if (projectableNodes !== undefined) {
                /** @type {?} */
                const projection = tElementNode.projection = [];
                for (let i = 0; i < this.ngContentSelectors.length; i++) {
                    /** @type {?} */
                    const nodesforSlot = projectableNodes[i];
                    // Projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade
                    // case). Here we do normalize passed data structure to be an array of arrays to avoid
                    // complex checks down the line.
                    // We also normalize the length of the passed in projectable nodes (to match the number of
                    // <ng-container> slots defined by a component).
                    projection.push(nodesforSlot != null ? Array.from(nodesforSlot) : null);
                }
            }
            // TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
            // executed here?
            // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
            component = createRootComponent(componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);
            renderView(rootTView, rootLView, null);
        }
        finally {
            leaveView();
        }
        /** @type {?} */
        const componentRef = new ComponentRef$1(this.componentType, component, createElementRef(ElementRef, tElementNode, rootLView), rootLView, tElementNode);
        if (!rootSelectorOrNode || isIsolated) {
            // The host element of the internal or isolated root view is attached to the component's host
            // view node.
            ngDevMode && assertNodeOfPossibleTypes(rootTView.node, 2 /* View */);
            (/** @type {?} */ (rootTView.node)).child = tElementNode;
        }
        return componentRef;
    }
}

Angular版本号维护在VERSION变量里:

在这里插入图片描述