作为angular应用的入口模块,了解他的重要性是显而易见的!今天闲来无事,便翻看@angular/platform-browser-dynamic源码,特此总结!希望观看过本篇文章对您有用!
main.ts是这个样子的,下面我就去解开platformBrowserDynamic神秘面纱!
import { platformBrowserDynamic } from 'iwe7/platform-browser-dynamic';platformBrowserDynamic() .bootstrapModule(AppModule) .catch(err => console.log(err));复制代码
platformBrowserDynamic源码
export const platformBrowserDynamic = createPlatformFactory( platformCoreDynamic, // 名字 'browserDynamic', // 注入所用到的服务 INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS);复制代码
platformCoreDynamic源码
export const platformCoreDynamic = createPlatformFactory( // @angular/core platformCore, // 名字 'coreDynamic', [ // 配置编译项目 { provide: COMPILER_OPTIONS, useValue: {}, multi: true }, { // 自定义jit编译工厂类,替换或实现原有的CompilerFactory,那么核心应该在这里了!! provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS] } ]);复制代码
通过查看源码,去伪存真,发现了他的核心JitCompilerFactory,下面看下JitCompilerFactory这个类
JitCompilerFactory源码,核心发放是createCompiler
export class JitCompilerFactory implements CompilerFactory { private _defaultOptions: CompilerOptions[]; /* @internal */ constructor(defaultOptions: CompilerOptions[]) { const compilerOptions: CompilerOptions = { useJit: true, // 配置试图 defaultEncapsulation: ViewEncapsulation.Emulated, missingTranslation: MissingTranslationStrategy.Warning }; this._defaultOptions = [compilerOptions, ...defaultOptions]; } createCompiler(options: CompilerOptions[] = []): Compiler { const opts = _mergeOptions(this._defaultOptions.concat(options)); const injector = Injector.create([ // 创建Compiler的核心 COMPILER_PROVIDERS, ]); return injector.get(Compiler); }}复制代码
发现核心关键COMPILER_PROVIDERS,顺藤摸瓜,找到了@angular/platform-browser-dynamic的核心
export const COMPILER_PROVIDERS =[ // 这里也是一个核心点-编译反射器 { provide: CompileReflector, useValue: new JitReflector() }, // ResourceLoader- 资源加载器 { provide: ResourceLoader, useValue: _NO_RESOURCE_LOADER }, // jit 摘要解析器 { provide: JitSummaryResolver, deps: [] }, // 摘要解析器 { provide: SummaryResolver, useExisting: JitSummaryResolver }, { provide: Console, deps: [] }, // 语法分析器 { provide: Lexer, deps: [] }, // 分析器 { provide: Parser, deps: [Lexer] }, { // 基本的HTML解析器 provide: baseHtmlParser, useClass: HtmlParser, deps: [] }, { // 国际化的HTML解析器 provide: I18NHtmlParser, useFactory: ( parser: HtmlParser, translations: string | null, format: string, config: CompilerConfig, console: Console ) => { translations = translations || ''; const missingTranslation = translations ? config.missingTranslation! : MissingTranslationStrategy.Ignore; // new 国际化的HTML解析器 return new I18NHtmlParser( parser, translations, format, missingTranslation, console ); }, deps: [ baseHtmlParser, [new Optional(), new Inject(TRANSLATIONS)], [new Optional(), new Inject(TRANSLATIONS_FORMAT)], [CompilerConfig], [Console] ] }, { provide: HtmlParser, useExisting: I18NHtmlParser }, { // 模板解析器 provide: TemplateParser, deps: [ CompilerConfig, CompileReflector, Parser, ElementSchemaRegistry, I18NHtmlParser, Console ] }, { // 指令 provide: DirectiveNormalizer, deps: [ResourceLoader, UrlResolver, HtmlParser, CompilerConfig] }, { // 元数据解析器 provide: CompileMetadataResolver, deps: [ CompilerConfig, HtmlParser, NgModuleResolver, DirectiveResolver, PipeResolver, SummaryResolver, ElementSchemaRegistry, DirectiveNormalizer, Console, [Optional, StaticSymbolCache], CompileReflector, [Optional, ERROR_COLLECTOR_TOKEN] ] }, DEFAULT_PACKAGE_URL_PROVIDER, // 样式编译器 { provide: StyleCompiler, deps: [UrlResolver] }, // view 编译器 { provide: ViewCompiler, deps: [CompileReflector] }, // ng module编译器 { provide: NgModuleCompiler, deps: [CompileReflector] }, // 编译器配置项目 { provide: CompilerConfig, useValue: new CompilerConfig() }, { // 编译器注入 provide: Compiler, // 这里也是一个核心 useClass: CompilerImpl, deps: [ Injector, CompileMetadataResolver, TemplateParser, StyleCompiler, ViewCompiler, NgModuleCompiler, SummaryResolver, CompileReflector, CompilerConfig, Console ] }, // dom schema { provide: DomElementSchemaRegistry, deps: [] }, // element schema { provide: ElementSchemaRegistry, useExisting: DomElementSchemaRegistry }, // url 解析 { provide: UrlResolver, deps: [PACKAGE_ROOT_URL] }, // dirctive 解析 { provide: DirectiveResolver, deps: [CompileReflector] }, // pipe 解析 { provide: PipeResolver, deps: [CompileReflector] }, // ng module 解析 { provide: NgModuleResolver, deps: [CompileReflector] }];复制代码
下面看看他的另外两个核心
- JitReflector
- CompilerImpl
JitReflector
export class JitReflector implements CompileReflector { private reflectionCapabilities: ReflectionCapabilities; constructor() { // @angular/core -> ɵReflectionCapabilities this.reflectionCapabilities = new ReflectionCapabilities(); } parameters(typeOrFunc: any): any[][] { return this.reflectionCapabilities.parameters(typeOrFunc); } annotations(typeOrFunc: any): any[] { return this.reflectionCapabilities.annotations(typeOrFunc); } shallowAnnotations(typeOrFunc: any): any[] { throw new Error('Not supported in JIT mode'); } tryAnnotations(typeOrFunc: any): any[] { return this.annotations(typeOrFunc); } propMetadata( typeOrFunc: any ): { [key: string]: any[]; } { return this.reflectionCapabilities.propMetadata(typeOrFunc); } // 解析生命周期钩子 hasLifecycleHook(type: any, lcProperty: string): boolean { return this.reflectionCapabilities.hasLifecycleHook(type, lcProperty); } guards( typeOrFunc: any ): { [key: string]: any; } { return this.reflectionCapabilities.guards(typeOrFunc); } // 组件url componentModuleUrl(type: any, cmpMetadata: Component): string { const moduleId = cmpMetadata.moduleId; if (typeof moduleId === 'string') { const scheme = getUrlScheme(moduleId); return scheme ? moduleId : `package:${moduleId}${MODULE_SUFFIX}`; } else if (moduleId !== null && moduleId !== void 0) { throw syntaxError( `moduleId should be a string in "${stringify(type)}". ` ); } return `./${stringify(type)}`; } resolveExternalReference(ref: ExternalReference): any { return builtinExternalReferences.get(ref) || ref.runtime; }}复制代码
CompilerImpl
export class CompilerImpl implements Compiler { private _delegate: JitCompiler; public readonly injector: Injector; constructor( injector: Injector, private _metadataResolver: CompileMetadataResolver, templateParser: TemplateParser, styleCompiler: StyleCompiler, viewCompiler: ViewCompiler, ngModuleCompiler: NgModuleCompiler, summaryResolver: SummaryResolver>, compileReflector: CompileReflector, compilerConfig: CompilerConfig, console: Console ) { this._delegate = new JitCompiler( _metadataResolver, templateParser, styleCompiler, viewCompiler, ngModuleCompiler, summaryResolver, compileReflector, compilerConfig, console, this.getExtraNgModuleProviders.bind(this) ); this.injector = injector; } private getExtraNgModuleProviders() { return [ this._metadataResolver.getProviderMetadata( new ProviderMeta(Compiler, { useValue: this }) ) ]; } // 懒加载了,应该是 compileModuleSync (moduleType: Type ): NgModuleFactory { return this._delegate.compileModuleSync(moduleType) as NgModuleFactory ; } compileModuleAsync (moduleType: Type ): Promise > { return this._delegate.compileModuleAsync(moduleType) as Promise< NgModuleFactory >; } compileModuleAndAllComponentsSync ( moduleType: Type ): ModuleWithComponentFactories { const result = this._delegate.compileModuleAndAllComponentsSync(moduleType); return { ngModuleFactory: result.ngModuleFactory as NgModuleFactory , componentFactories: result.componentFactories as ComponentFactory [] }; } compileModuleAndAllComponentsAsync ( moduleType: Type ): Promise > { return this._delegate .compileModuleAndAllComponentsAsync(moduleType) .then(result => ({ ngModuleFactory: result.ngModuleFactory as NgModuleFactory , componentFactories: result.componentFactories as ComponentFactory [] })); } loadAotSummaries(summaries: () => any[]) { this._delegate.loadAotSummaries(summaries); } hasAotSummary(ref: Type ): boolean { return this._delegate.hasAotSummary(ref); } getComponentFactory (component: Type ): ComponentFactory { return this._delegate.getComponentFactory(component) as ComponentFactory ; } clearCache(): void { this._delegate.clearCache(); } clearCacheFor(type: Type ) { this._delegate.clearCacheFor(type); }}复制代码
下面调试一下前面分析的几个核心,我就不分顺序了。
JitReflector->hasLifecycleHook
生命周期检测!
JitReflector->guards
路由守卫
JitReflector->componentModuleUrl
获取componentModule的路径,如: ./AppComponent
CompilerImpl->compileModuleSync
异步编译模块
CompilerImpl->compileModuleAsync
异步编译模块
CompilerImpl->compileModuleAndAllComponentsSync
编译模块下的component
CompilerImpl->compileModuleAndAllComponentsAsync
异步编译模块下的component
CompilerImpl->getComponentFactory
获取ComponentFactory实例
项目启动后可以保存项目实例,以便不时只需!
declare const window: any;let ref1 = platformBrowserDynamic([]) .bootstrapModule(AppModule) .then(res => { window.meepo = res; }) .catch(err => console.log(err));复制代码
总结
ng的代码写的蛮规范的,闲来无事可以翻阅!以上代码仅是摘录!具体可看@angular/platform-browser-dynamic