If you missed it — check out Part 1 of this series! ’ on up! Now we’re diving in to an application. Since we’re focusing on the basic model given by the ng cli, we’ll take a look at the simple bootstrap contained within application_ref.ts. Movin bootstrapping In ApplicationRef_ the actually just contains a simple call to a private method, _bootstrapModuleWithZone. If you missed my brief overview on zones, you can find it , but I’ll do a deeper article at some point in this series as well. implementation of bootstrapModule here First off we notice that now we instantiate a compiler; const compilerFactory: CompilerFactory =this.injector.get(CompilerFactory);const compiler = compilerFactory.createCompiler(Array.isArray(compilerOptions) ?compilerOptions : [compilerOptions]); If you’ll recall from Part 1, the compiler that comes with the dynamicBrowserPlatform is the . Looking into the createCompiler method, the code makes an injector, which provides the config that was passed in via the Factory’s constructor, and then gets the Compiler from the injector. RuntimeCompilerFactory What does the compiler look like? Well, although the COMPILER_PROVIDERS specifically call out many compilers, assigns the Compiler we’re looking for. The compiler provided here is the , an internal class of the Angular2 framework that compiles templates and components dynamically for use in the app. RuntimeCompiler is a subclasses . Remember the RuntimeCompiler, as we’ll come back to it shortly. this line RuntimeCompiler Compiler Continuing moving through , the third argument is componentFactoryCallback. The method that calls bootstrapModuleWithZone in _bootstrapModule calls it like this; _bootstrapModuleWithZone this._bootstrapModuleWithZone(moduleType, compilerOptions, null); in other words, there is no callback. The method instead returns a call to the compiler, , with an argument of the moduleType, which is in our case is our AppModule. That’s right, the first piece of code that we actually supplied (kind of) has entered the equation. compileModuleAsync compileModuleAsync, in turn, calls a private method, _compileModuleAndComponents, with the first argument being our AppModule, and the second being a boolean that tells the compiler whether it should perform the compile asynchronously. The method looks like this, const componentPromise = this._compileComponents(moduleType,isSync);const ngModuleFactory = this._compileModule(moduleType); return new SyncAsyncResult(ngModuleFactory,componentPromise.then(() => ngModuleFactory)); Diving into the method, the first line that isn’t a simple declaration is this; _compileComponents const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule); Where mainModule is the AppModule provided by ng-cli’s boilerplate. The _metadataResolver comes into the RuntimeCompiler as a private property injected from the Compiler’s constructor. In , let’s take a look at , and what the response looks like. CompileMetadataResolver what happens to get the module metadata First we resolveForwardRef, which the developers of Angular2 were nice enough to give a . This forward reference allows the resolution of a class that isn’t necessarily inline before the CompileMetadataResolver. plnkr example of Moving on, the code then checks to see if the moduleType has already been compiled and retrieve it from the cache, var compileMeta = this._ngModuleCache.get(moduleType); Since this is our first execution of the code, we assume this is undefined and continue on. The code then attempts to resolve the metadata for the module via , another injected private property. _ngModuleResolver leads us to an actually relatively simple class, simple enough that I can replicate it below; NgModuleResolver @Injectable()export class NgModuleResolver {constructor(private _reflector: ReflectorReader = reflector) {} resolve(type: Type<any>, throwIfNotFound = true): NgModule {const ngModuleMeta: NgModule =this._reflector.annotations(type).find(_isNgModuleMetadata);if (isPresent(ngModuleMeta)) {return ngModuleMeta;} else {if (throwIfNotFound) {throw new Error(`No NgModule metadata found for '${stringify(type)}'.`);}return null;}}} So this asks the for information about the specific annotations for our module. Reflector is actually injected and instantiated way back (from part 1) in our platform_core_providers, and the ReflectionCapabilities, which Reflector draws from, are actually just the default implementation found . Reflector here We’re most curious right now about the , so let’s take a look. Before looking at this code, it might be useful to . So, our AppModule in fact have an annotation, and . annotations have a look at Paschal Precht’s article about Annotations vs. Decorators does the reflector will look for .annotations or .decorators and return the relevant NgModule annotation Stepping back out to this code; function _isNgModuleMetadata(obj: any): obj is NgModule {return obj instanceof NgModule;} ... const ngModuleMeta: NgModule = this._reflector.annotations(type).find(_isNgModuleMetadata); We find the specific annotation that is an instance of NgModule, corresponding to the @NgModule({...})export class AppModule { } From our own code. The contents of the NgModule annotation are now assigned to and returned from the NgModuleResolver. ngModuleMeta We’re now back with the successfully resolved meta information provided by the NgModule annotation. I’ll leave it here, as I think this article has gone on long enough. Keep an eye out for Part 3 when we delve into the resolution of the NgModule metadata! here is how hackers start their afternoons. We’re a part of the family. We are now and happy to opportunities. Hacker Noon @AMI accepting submissions discuss advertising &sponsorship To learn more, , , or simply, read our about page like/message us on Facebook tweet/DM @HackerNoon. If you enjoyed this story, we recommend reading our and . Until next time, don’t take the realities of the world for granted! latest tech stories trending tech stories