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

宗建章
2023-12-01

作为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 = <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] }
];
复制代码

下面看看他的另外两个核心

  • 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<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

 类似资料: