作为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