web-dev-qa-db-ja.com

angularコンパイラは何を「コンパイル」しますか?

今日はそのように頼まれ、適切な答えを出すことができませんでした。

TypeScriptはJSにトランスパイルします。次に、ツリーの揺れ、「少ない」(オプション)、および展開の過程で他に何があります。しかし、そのようなもの(afaik)は「コンパイル」とは何の関係もありません。すべてがバンドルされ、高度に最適化されていますが、実際にはコンパイルされていませんよね?

前もってコンパイラーさえあり、それは本当に顕著な仕事をします。私は何が恋しいですか?

Javascript自体はまだ解釈されていますよね?

81
codepleb

コンパイルとは、ソースコードを取得し、マシンコード、低レベルコードなどを生成することを意味します。しかし、実際には、コンパイルは、あるソースコードを取得して別のソースコードに変換することを意味します。そのため、TypeScriptを使用してJavaScriptを生成することは、コンパイルのformであると言うのが妥当と思われます。 IL言語にコンパイルされたc#が(たとえば)何をするかと似ています。

そうは言っても、このためのより良いWordはTranspilingです。 TypeScriptコンパイラはbetterTranspilerとして記述されることをお勧めします。

違いはわずかであり、トランスパイラーはコンパイラーの一種と考えることができます。しかし、(純粋な)コンパイルされた言語は、(通常)C#の例のように、高レベル言語を低(低)レベル言語(マシンコードに近い)に変えることです。トランスパイラーは、高レベル言語を同様のレベルの(抽象化)言語(高レベル)に変換します。*

コンパイルされたコードの結果は通常自分で書く言語ではないです。トランスパイラーの結果は、別の高レベル言語です。理論的には、ILを(例として)書くことができますが、実際にはコンパイラによって作成されるように設計されており、これを行うためのツールやサポートはありません。C#/ vb.netをコンパイルするだけでILを作成できます。一方、Javascriptはそれ自体で使用可能な(使用されている)プログラミング言語です。

*これらの単語の定義とその用法はかなり曖昧なので、多くの警告

88
Liam

あなたは1つで3つの質問をしているようです:

  • コンパイラとトランスパイラーの違いは何ですか?
  • AngularとTypeScriptはコンパイラーまたはトランスパイラーを実装していますか?
  • 別のAngularコンパイラはありますか?何をコンパイルしますか?

コンパイラとトランスパイラーの違いは何ですか?

@JörgWMittagは この質問に対して非常に良い回答 を提供しました。

AngularとTypeScriptはコンパイラーまたはトランスパイラーを実装していますか?

TSとAngularの両方がrealコンパイラを実装しています。これらは、アセンブリコードを生成するC/C++コンパイラと同じ語彙分析、解析、セマンティック分析、およびコード生成の段階に従います(おそらく最適化を除く)。 AngularTS の両方で、クラス/フォルダーの名前が「コンパイラー」であることがわかります。

angularコンパイラは、TypeScriptコンパイラと実際には関係ありません。これらは非常に異なるコンパイラです。

別のAngularコンパイラはありますか?何をコンパイルしますか?

Angularには2つのコンパイラがあります:

  • コンパイラを表示
  • モジュールコンパイラ

ビューコンパイラの仕事は、コンポーネントテンプレートに指定したテンプレートを、ビューファクトリであるコンポーネントの内部表現に変換することですviewインスタンスのインスタンス化に使用されます

ビューコンパイラは、テンプレートの変換に加えて、@HostBinding@ViewChildなどのようなデコレータの形式でさまざまなメタデータ情報もコンパイルします。

次のようにコンポーネントとそのテンプレートを定義するとします。

@Component({
  selector: 'a-comp',
  template: '<span>A Component</span>'
})
class AComponent {}

このデータを使用して、コンパイラは次のわずかに簡略化されたコンポーネントファクトリを生成します。

function View_AComponent {
  return jit_viewDef1(0,[
      elementDef2(0,null,null,1,'span',...),
      jit_textDef3(null,['My name is ',...])
    ]

コンポーネントビューの構造を記述し、コンポーネントをインスタンス化するときに使用されます。最初のノードは要素定義で、2番目のノードはテキスト定義です。パラメーターリストを介してインスタンス化されると、各ノードが必要な情報を取得することがわかります。必要な依存関係をすべて解決し、実行時に提供するのはコンパイラーの仕事です。

これらの記事を読むことを強くお勧めします。

  • Angular の動的コンポーネントについて知っておくべきこと
  • Angular 内にコンポーネントが見つからない理由はここにあります

また、 Angular AOTとJITコンパイラの違いは何ですか?

モジュールコンパイラの仕事は、基本的にプロバイダのマージされた定義を含むモジュールファクトリを作成することです。

詳細については、次をお読みください。

  • Angular のモジュールとの一般的な混乱の回避

TypeScriptはJSに変換されます。次に、ツリーの揺れ、「少ない」(オプション)、および展開の過程で他に何があります。しかし、そのようなもの(afaik)は「コンパイル」とは何の関係もありません。すべてがバンドルされ、高度に最適化されていますが、実際にはコンパイルされていませんよね?

Compilationは、言語で記述されたプログラムをA言語で記述された意味的に等価なプログラムに変換することを意味しますB言語の規則に従ってコンパイルされたプログラムを評価するB(たとえばBのインタープリターで解釈すると同じ結果になる)結果であり、言語の規則に従って元のプログラムを評価するのと同じ副作用がありますA(たとえばAのインタープリターで解釈する)。

コンパイルとは、単にプログラムを言語Aから言語Bに翻訳することを意味します。それだけです。 (ABが同じ言語になることも完全に可能であることに注意してください。)

場合によっては、AおよびBが何であるか、およびコンパイラーが何をするかに応じて、特定の種類のコンパイラーにより特化した名前を付けることがあります。

  • Aがアセンブリ言語であると認識され、Bが機械語であると認識される場合、アセンブラと呼びます
  • Aが機械語であると認識され、Bがアセンブリ言語であると認識される場合、逆アセンブラーと呼びます
  • ABよりも低いレベルであると認識されている場合、それを(decompiler
  • ABが同じ言語であり、結果のプログラムが何らかの方法で高速または軽量である場合、オプティマイザー
  • ABが同じ言語であり、結果のプログラムがより小さい場合、それをminifier
  • ABが同じ言語であり、結果のプログラムが読みにくい場合、難読化ツールと呼びます
  • AおよびBがほぼ同じレベルの抽象化であると認識されている場合、これをtranspiler、および
  • AおよびBがほぼ同じレベルの抽象化であると認識され、結果のプログラムがフォーマット、コメント、およびプログラマーの意図を保持する場合元のプログラムと同じ方法で結果のプログラムを維持するために、リエンジニアリングツールと呼びます。

また、古いソースでは、「コンパイル」と「コンパイラ」の代わりに「翻訳」と「翻訳者」という用語が使用される場合があることに注意してください。たとえば、Cは「翻訳単位」について話します。

「言語プロセッサ」という用語に出くわすこともあります。これは、定義に応じて、コンパイラー、インタープリター、またはコンパイラーとインタープリターの両方を意味します。

Javascript自体はまだ解釈されますよね?

JavaScriptは言語です。言語は、論理的な規則と制限のセットです。言語は解釈もコンパイルもされません。言語はareです。

コンパイルと解釈は、コンパイラーまたはインタープリターの特性です(ダァ!)。すべての言語はコンパイラーで実装でき、すべての言語はインタープリターで実装できます。多くの言語には、コンパイラとインタープリターの両方があります。多くの最新の高性能実行エンジンには、少なくとも1つのコンパイラと少なくとも1つのインタープリターがあります。

これらの2つの用語は、抽象化の異なる層に属します。英語が型付き言語である場合、「interpreted-language」は型エラーになります。

また、一部の言語にはインタプリタもコンパイラもありません。まったく実装されていない言語があります。それでも、それらは言語であり、プログラムを作成できます。それらを実行することはできません。

また、すべてがいくつかのポイントで解釈されることに注意してください:何かを実行したい場合は、must解釈します。コンパイルはコードをある言語から別の言語に翻訳するだけです。実行されません。 Interpretationはそれを実行します。 (時には、インタープリターがハードウェアに実装されている場合、「CPU」と呼びますが、それでもインタープリターです。)

適切な例:現在存在する主流のJavaScript実装にはすべてコンパイラーがあります。

V8は純粋なコンパイラーとして始まりました。JavaScriptを適度に最適化されたネイティブマシンコードに直接コンパイルしました。その後、2番目のコンパイラが追加されました。現在、2つのコンパイラがあります。適度に最適化されたコードを生成する軽量コンパイラですが、コンパイラ自体は非常に高速で、RAMをほとんど使用しません。また、このコンパイラは、コンパイルされたコードにプロファイリングコードを挿入します。 2番目のコンパイラーは、より重く、より遅く、より高価なコンパイラーですが、よりタイトでずっと速いコードを生成します。また、最初のコンパイラによって注入されたプロファイリングコードの結果を使用して、動的最適化の決定を行います。また、2番目のコンパイラを使用して再コンパイルするコードの決定は、そのプロファイリング情報に基づいて行われます。通訳者がいないことに注意してください。 V8は解釈することはなく、常にコンパイルします。インタプリタさえ含まれていません。 (実際、最近はそうだと思いますが、最初の2つの反復について説明しています。)

SpiderMonkeyはJavaScriptをSpiderMonkeyバイトコードにコンパイルし、それを解釈します。インタープリターはコードのプロファイリングも行います。その後、最も頻繁に実行されるコードがコンパイラーによってネイティブマシンコードにコンパイルされます。そのため、SpiderMonkeyにはtwoコンパイラが含まれています。1つはJavaScriptからSpiderMonkeyバイトコードまで、もう1つはSpiderMonkeyバイトコードからネイティブマシンコードまでです。

ほとんどすべてのJavaScript実行エンジン(V8を除く)は、JavaScriptをバイトコードにコンパイルするAOTコンパイラのこのモデルと、そのバイトコードの解釈とコンパイルを切り替える混合モードエンジンに従います。

あなたはコメントで書いた:

マシンコードはどこかに関係していると本当に思っていました。

「マシンコード」とはどういう意味ですか?

ある人の機械語と別の人の中間言語、およびその逆は何ですか?たとえば、JVMバイトコードをネイティブに実行できるCPUがあります。そのようなCPUでは、JVMバイトコードisネイティブマシンコードです。また、x86マシンコードisで解釈されたバイトコードを実行すると、x86マシンコード用のインタープリターがあります。

Javaで記述されたJPCと呼ばれるx86インタープリターがあります。ネイティブJVM CPUで実行されているJPCでx86マシンコードを実行する場合…バイトコードとネイティブコードはどちらですか? x86マシンコードをJavaScriptにコンパイルし(そうすることができるツールがあります)、携帯電話のブラウザー(ARM CPUを持つ)で実行します。これはバイトコードであり、ネイティブマシンコード?コンパイルしているプログラムがSPARCエミュレーターであり、それを使用してSPARCコードを実行するとどうなりますか?

every言語は抽象マシンを誘発し、そのマシンのマシン言語であることに注意してください。したがって、すべての言語(非常に高レベルの言語を含む)はネイティブマシンコードです。また、すべての言語のインタープリターを作成できます。そのため、すべての言語(x86マシンコードを含む)はネイティブではありません。

49
Jörg W Mittag

ブラウザーで実行するために作成したコードを取得するには、2つのことが必要です。

1)TypeScriptをJavaScriptに変換します。これは一種の解決された問題です。彼らはただwebpackを使用していると思う。

2)angular抽象化をJavaScriptにコンパイルします。コンポーネント、パイプ、ディレクティブ、テンプレートなどのようなものを意味します。これがangularコアチームが取り組んでいるものです。

2番目のビットangularコンパイラに本当に興味がある場合は、 コンパイラ作成者のTobias BoschがAngularConnect 2016でAngularコンパイラを説明します

トランスコンパイルとコンパイルの間でここで少し混乱が起こっていると思います。それは問題ではなく、個人的な好みの問題であり、どちらもコードの表現間の変換にすぎません。しかし、私が個人的に使用する definition は、transpilationが同様の抽象化レベルの2つの異なる言語間(TypeScriptからjavascriptへ)であるということです。 、compilationは抽象化レベルを下げる必要があります。テンプレート、コンポーネント、パイプ、ディレクティブなどからjavascriptに至るまでが抽象化の梯子の一歩であり、それがコンパイラと呼ばれる理由だと思います。

16
Nathan Cooper