В чем разница между Angular AOT и JIT-компилятором
я погружаюсь в angular 4, и я пытаюсь понять компиляцию. Я читал, что AOT и JIT оба компилируют TypeScript в JavaScript, будь то на стороне сервера или на стороне клиента. Если я компилирую его, когда я создаю его с помощью Webpack и grunt и развертываю этот мини-javascript, как AOT и JIT даже входят в картину?
3 ответов
Я читал, что AOT и JIT оба компилируют TypeScript в JavaScript будь то на стороне сервера или на стороне клиента.
нет, это не то, что делают компиляторы AOT и JIT. TypeScript транспилируется в JavaScript с помощью компилятора typescript.
Угловое компилятор
есть два компилятора, которые выполняют тяжелую работу компиляции и генерации кода:
компилятор представления компилирует шаблоны компонентов и генерирует view factories. Он анализирует выражения и html-элементы внутри шаблона и проходит через многие стандартные фазы компилятора:
parse-tree (lexer) -> abstract-syntax-tree (parser) -> intermediate-code-tree -> output
компилятор провайдера компилирует провайдеров модулей и генерирует модуль фабрики.
JIT vs AOT
эти два компиляторы используются как в JIT, так и в компиляции AOT. Компиляции JIT и AOT отличаются тем, как они получают метаданные, связанные с компонентом или модулем:
// the view compiler needs this data
@Component({
providers: ...
template: ...
})
// the provider compiler needs this data
@NgModule({
providers: ...
});
компилятор JIT использует среду выполнения для получения данных. Функции декоратора @Component
и @NgModule
выполнены и они придают метаданных к компоненту или классу модуля, который позже читается угловыми компиляторами с использованием отражающих capabiliteis (Reflect library).
компилятор AOT использует статический код анализ, предоставляемый компилятором typescript для извлечения метаданных и не зависит от оценки кода. Следовательно, он немного ограничен по сравнению с JIT-компилятором, поскольку он не может оценивать явный код-например, он требует экспорта функции:
// this module scoped function
function declarations() {
return [
SomeComponent
]
}
// should be exported
export function declarations() {
return [
SomeComponent
];
}
@NgModule({
declarations: declarations(),
})
export class SomeModule {}
опять же, компиляторы JIT и AOT в основном являются оболочками для извлечения метаданных, связанных с компонентом или модулем, и они оба используют базовый вид и компилятор поставщика для создания фабрик.
Если Я компилирую его, когда я создаю его с помощью Webpack и grunt и развертывание этого уменьшенного javascript, как AOT и JIT даже входят фотографию?
Угловое обеспечивает плагин webpack который выполняет транспиляцию из typescript во время сборки. Этот плагин также может скомпилировать ваш проект, чтобы вы не включали JIT-компилятор в пакет и не выполняли компиляцию на клиенте.
прежде всего угловой уходит от компиляции JIT. Надеюсь, мы увидим это в angular@5.x.x
угловой компилятор принимает все метаданные, которые вы пишете, используя декораторы, такие как
@Component({
selector: 'my-app',
template: '<h1>Hello</h1>'m
styles: [ ':host { display: block }' ]
})
constructor(
@Host() @Optional() private parent: Parent,
@Attribute('name') name: string) {}
@ViewChild('ref') ref;
@ContentChildren(MyDir) children: QueryList<MyDir>;
@HostBinding('title') title;
@HostListener('click') onClick() { ... }
// and so on
и анализирует его. Затем он берет шаблон и таблицы стилей и анализирует их. Компилятор проходит много шагов, которые я не буду описывать здесь. Вы можете взглянуть на Следующая страница это описывает процесс компиляции. Существует также большой разговор Тобиас Босх. Наконец, компилятор создает ngfactories для создания экземпляра нашего приложения.
я думаю, что основные различия между AOT в JIT являются
- когда и где angular запускает компиляцию
- как компилятор собирает метаданные
- какой формат
ngfactory
что компилятор выдает
JIT-компилятор
работает на стороне клиента в нашем браузере на каждой странице загрузки.
он собирает метаданные с помощью ReflectionCapabilities API С @angular/core
пакета. У нас есть следующие опции для работы с метаданными в режиме JIT:
1) Прямой API
например, мы можем объявить наш компонент, как
export class AppComponent {
static annotations = [
new Component({
selector: 'my-app',
templateUrl: `./app.component.html`,
styles: [ ':host { display: block }' ]
})
];
test: string;
static propMetadata = {
test: [new HostBinding('title')]
};
ngOnInit() {
this.test = 'Some title'
}
}
подобный код мы можем написать в ES5. JIT-компилятор будет читать annotations
и propMetadata
статические свойства. Компилятор AOT не будет работать с ним.
2) tsickle В API
export class AppComponent {
static decorators = [{
type: Component,
args: [{
selector: 'my-app',
templateUrl: `./app.component.html`,
styles: [ ':host { display: block }' ]
},]
}];
test: string;
static propDecorators = {
'test': [{ type: HostBinding, args: ['title'] }]
};
ngOnInit() {
this.test = 'Some title'
}
}
приведенный выше код обычно генерируется некоторыми библиотеке. Угловой пакет также имеет такой же формат. Это также не будет работать с АОТ. Мы должны отправить metadata.json
файл с нашей библиотекой для компиляции AOT.
3) Получение метаданных, созданных путем вызова декораторов
@Component({
selector: 'my-app',
templateUrl: `./app.component.html`
})
export class AppComponent {
@HostBinding('title') test = 'Some title';
}
компилятор Typescript преобразует предыдущий код в
var AppComponent = (function () {
function AppComponent() {
this.test = 'Some title';
}
return AppComponent;
}());
__decorate([
HostBinding('title')
], AppComponent.prototype, "test", void 0);
AppComponent = __decorate([
Component({
selector: 'my-app',
templateUrl: "./app.component.html"
})
], AppComponent);
этот код выполняется в режиме JIT так угловой вызовы компонент декоратор!--34-->
const TypeDecorator: TypeDecorator = <TypeDecorator>function TypeDecorator(cls: Type<any>) {
// Use of Object.defineProperty is important since it creates non-enumerable property which
// prevents the property is copied during subclassing.
const annotations = cls.hasOwnProperty(ANNOTATIONS) ?
(cls as any)[ANNOTATIONS] :
Object.defineProperty(cls, ANNOTATIONS, {value: []})[ANNOTATIONS];
annotations.push(annotationInstance);
return cls;
};
сегодня больше не использует Reflect api. Компилятор считывает данные непосредственно из __annotations__
свойства
if (typeOrFunc.hasOwnProperty(ANNOTATIONS)) {
return (typeOrFunc as any)[ANNOTATIONS];
}
JIT-компилятор производит javascript ngfactories
компилятор AOT
работает на стороне сервера (nodejs) во время сборки с помощью ngc
.
С AOT нет шага компиляции во время выполнения. Когда мы запускаем наше приложение в браузере мы уже прекомпилированные ngfactories
. Это дает нам лучшую производительность сначала и ленивую нагрузку. Мы также не грузим @angular/compiler
код в нашем производственном комплекте больше. Но наш пучок может значительно вырасти из-за нашего ngfactories
код.
компилятор AOT использует машинопись с API для анализа кода typescript. Для получения метаданных компилятор проходит через StaticSymbolResolver и MetadataCollector API-интерфейсы.
так что это занимает и создает объектную модель typescript. Так наши AppComponent
класс будет представлен как NodeObject
С типом 229
(ClassDeclaration
)
как мы видим этот объект имеет decorators
свойства
и специальная обертка для машинописи, написанная угловой командой и называемая tsc-wrapper
делает тяжелую работу для извлечения этих метаданных.
когда компилятор отвечает он пытается получить метаданные из metadata.json
:
if (DTS.test(filePath)) {
var metadataPath = filePath.replace(DTS, '.metadata.json');
if (this.context.fileExists(metadataPath)) {
return this.readMetadata(metadataPath, filePath);
}
else {
// If there is a .d.ts file but no metadata file we need to produce a
// v3 metadata from the .d.ts file as v3 includes the exports we need
// to resolve symbols.
return [this.upgradeVersion1Metadata({ '__symbolic': 'module', 'version': 1, 'metadata': {} }, filePath)];
}
}
и, наконец, компилятор AOT использует TypeScriptEmitter to производить typescript ngfactories (угловые
см. также
после загрузки браузером пакетов приложений угловой компилятор (упакованный внутри поставщика.пачка.js) выполняет компиляцию шаблонов из main.пачка.js. Это называется компиляцией Just-in-Time. Этот термин означает, что компиляция происходит во время прибытия пакетов в браузер.
недостатками компиляции JIT являются:
существует временной промежуток между загрузкой пакетов и отображением пользовательского интерфейса. Это время тратится на JiT сборник. На маленьком приложении это время минимально, но в больших приложениях компиляция JiT может занять пару секунд, поэтому пользователю нужно ждать дольше, чтобы просто увидеть ваше приложение.
угловой компилятор должен быть включен в поставщика.пачка.js, который добавляет к размеру вашего приложения.
использование компиляции JiT в prod не рекомендуется, и мы хотим, чтобы шаблоны были предварительно скомпилированы в JavaScript до создания пакетов. Этот это то, о чем идет компиляция Ahead-of-Time (AoT).
преимущества компиляции AoT:
браузер может отображать пользовательский интерфейс, как только приложение загружается. Нет необходимости ждать компиляции кода.
компилятор ngc не входит в состав поставщика.пачка.js и результирующий размер вашего приложения могут быть меньше.
Если вы используете Webpack, чтобы сделать AoT, вам нужно вызвать ngc компилятор. Например:
"build:aot": "ngc -p tsconfig.json && webpack --config webpack.config.js"