В чем разница между 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"
            
