深度解析@angular/platform-browser-dynamic

做爲angular應用的入口模塊,瞭解他的重要性是顯而易見的!今天閒來無事,便翻看@angular/platform-browser-dynamic源碼,特此總結!但願觀看過本篇文章對您有用!bootstrap

main.ts是這個樣子的,下面我就去解開platformBrowserDynamic神祕面紗!bash

import { platformBrowserDynamic } from 'iwe7/platform-browser-dynamic';
platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.log(err));
複製代碼

platformBrowserDynamic源碼dom

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這個類ide

JitCompilerFactory源碼,核心發放是createCompilerui

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的核心this

export const COMPILER_PROVIDERS = <StaticProvider[]>[
  // 這裏也是一個核心點-編譯反射器
  { 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] }
];
複製代碼

下面看看他的另外兩個核心url

  • JitReflector
  • CompilerImpl

JitReflectorspa

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<Type<any>>,
    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<T>(moduleType: Type<T>): NgModuleFactory<T> {
    return this._delegate.compileModuleSync(moduleType) as NgModuleFactory<T>;
  }
  compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> {
    return this._delegate.compileModuleAsync(moduleType) as Promise<
      NgModuleFactory<T>
    >;
  }
  compileModuleAndAllComponentsSync<T>(
    moduleType: Type<T>
  ): ModuleWithComponentFactories<T> {
    const result = this._delegate.compileModuleAndAllComponentsSync(moduleType);
    return {
      ngModuleFactory: result.ngModuleFactory as NgModuleFactory<T>,
      componentFactories: result.componentFactories as ComponentFactory<any>[]
    };
  }
  compileModuleAndAllComponentsAsync<T>(
    moduleType: Type<T>
  ): Promise<ModuleWithComponentFactories<T>> {
    return this._delegate
      .compileModuleAndAllComponentsAsync(moduleType)
      .then(result => ({
        ngModuleFactory: result.ngModuleFactory as NgModuleFactory<T>,
        componentFactories: result.componentFactories as ComponentFactory<any>[]
      }));
  }
  loadAotSummaries(summaries: () => any[]) {
    this._delegate.loadAotSummaries(summaries);
  }
  hasAotSummary(ref: Type<any>): boolean {
    return this._delegate.hasAotSummary(ref);
  }
  getComponentFactory<T>(component: Type<T>): ComponentFactory<T> {
    return this._delegate.getComponentFactory(component) as ComponentFactory<T>;
  }
  clearCache(): void {
    this._delegate.clearCache();
  }
  clearCacheFor(type: Type<any>) {
    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

相關文章
相關標籤/搜索