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


88

今日はそれを聞かれ、適切な答えを出すことができませんでした。

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

「事前」コンパイラーもあります。これは本当に注目に値する仕事をします。何が恋しいですか?

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


6
私は「実際にはコンパイルしない」ことに同意します。本質的に、それはコンパイルの定義の問題です。TypeScriptからJavaScriptへの変換をマークするためにtranspilationという単語を使用することを好む人もいます。しかし、ええ、本質的に、Typescriptコンパイラの役割はTypescriptからJavascriptを生成することだけです。
pac0 2017年

6
@ Pac0ここで何か誤解しているかもしれませんが、TypeScriptからJavaScriptへのトランスパイルの場合、GCCはCからマシンコードへのトランスパイラーではないでしょうか。トランスパイラーとコンパイラの違いをどのように定義しますか?
11684 2017年

24
トランスパイラーはコンパイラーです
user253751 2017年

5
「トランスパイラー」と言うとき、人々はどういう意味ですか?を参照してください(そしてフォローアップ「私の最初の15個のコンパイラ」)(コンパイラに取り組んでいる人から)、これは「コンパイラ」がこのようなものに使用するのに良い言葉であると主張しています。
ShreevatsaR 2017年

2
Javascript自体はまだ解釈されていますよね?-これ以上、V8エンジンによってオンザフライでマシンコードにコンパイルされます
Max Koretskyi 2017年

回答:


91

コンパイルとは、ソースコードを取得してマシンコード、低レベルコードなどを生成することを意味すると想定しています。しかし、実際には、コンパイルとは、あるソースコードを取得して別のソースコードに変換することを意味します。したがって、Typescriptを使用してJavaScriptを作成することは、コンパイルの一形態であると言っても過言ではありません。これは、(たとえば)c#がIL言語にコンパイルされたときに実行することと同じです。

そうは言っても、これについてのより良い言葉はTranspilingだ思います。TypescriptコンパイラはTranspilerとしてより適切に説明することをお勧めします。

違いは微妙で、トランスパイラーは一種のコンパイラーと考えることができます。しかし、(純粋な)コンパイル言語は、(通常)C#の例のように、高水準言語を低水準言語(機械語に近い)に変換します。トランスパイラーは、高水準言語を(抽象化の)同様のレベルの言語(これも高水準)に変換します。*

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

*これらの単語の定義とその使用法はかなり曖昧であるため、多くの警告があります


12
JavaScriptはTypeScriptよりも厳密に低レベルではありませんか?
ベルギ

3
この回答のすべてが正しくて役立ちますが、特にコンパイルの定義は常に混乱の問題であるため、タイトルの質問には答えません。この回答はTypeScriptについてのみ説明していますが、質問はAngularについてです。違いは大きいです。TSが問題であることを知らなくても、Angularを使用することは完全に可能です。この答えが受け入れられたのには驚きました。
ペドロA

3
コンパイラは、別のプログラムを生成するために、基本的にプログラム全体を理解する必要があります(通常は同じことを行いますが、別の言語で行います。これにはマシンコードが含まれます)。
–ThorbjørnRavn Andersen 2017

8
私はそれを2回読んだだけで、ここで質問に対する答えを見つけることができませんでした。答えはすぐ下にあります。
kuncevic.dev 2017年

5
OPが尋ねていた暗黙の質問は、これを受け入れた理由であり、「Angularコンパイラをコンパイラと呼ぶのは正しいですか?」でした。—そしてそれがこの答えが答えるものです。だから私から+1。「トランスパイラー」と言うとき、人々はどういう意味ですか?も参照してくださいそしてフォローアップ「私の最初の15のコンパイラ」
ShreevatsaR 2017年

70

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

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

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

@JörgWMittagこの質問に非常に良い答え提供しました

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

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

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

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

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

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

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

テンプレートを変換するほかに、ビューコンパイラはまた、のようなデコレータの形で様々なメタデータ情報をコンパイルし@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番目のノードはテキスト定義です。パラメータリストを介してインスタンス化されると、各ノードが必要な情報を取得することがわかります。必要なすべての依存関係を解決し、実行時にそれらを提供するのはコンパイラーの仕事です。

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

また、AngularAOTコンパイラとJITコンパイラの違いは何ですか?の回答を参照してください

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

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



1
@codepleb GCCや他の多くのコンパイラは、マシンコードをまったく生成しないことに注意してください。実際には、GCCは自動的にシステムを呼び出してマシンコードを生成しますが、外部の支援なしで生成するコードは単なるアセンブリであり、外部のアセンブラに渡されます。
prosfilaes 2017年

7
@codeplebこの回答ははるかに優れており、実際にあなたの質問に答えます。あなたの最初の判断を再考する時間はまだあります。
非同期2017年

3
@codepleb「トランスパイラー」という用語が存在する、または存在したことのある正当な理由はありません。誤解を招くだけです。
Leushenko 2017年

2
@stom、申し訳ありませんが、その質問は広すぎます。しかし、最も賛成された答えはかなり良いです
Max Koretskyi 2018

54

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

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

コンパイルとは、プログラムを言語Aから言語Bに翻訳することを意味します。それが意味するすべてです。(また、ABが同じ言語である可能性も完全にあります。)

場合によっては、ABが何であるか、およびコンパイラーが何をするかに応じて、特定の種類のコンパイラーに対してより特殊な名前が付けられます。

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

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

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

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

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

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

これらの2つの用語は、異なる抽象化レイヤーに属しています。英語が型付き言語である場合、「インタープリター型言語」は型エラーになります。

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

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

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

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

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

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

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

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

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

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

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

すべての言語は抽象機械を誘発し、その機械の機械語であることに注意しください。したがって、すべての言語(非常に高水準の言語を含む)はネイティブマシンコードです。また、すべての言語の通訳を書くことができます。したがって、すべての言語(x86マシンコードを含む)はネイティブではありません。


4
コンパイルの概念の詳細な説明については+1、可能であれば、それらの箇条書きについてはさらに+1します。非常に役立ちます。
ペドロA

1
とはいえ、技術的にはこれはタイトルの質問に答えるものではありません...それでも私からは+1に値します!
ペドロA

私はそれが暗黙的であることに同意しますが、タイトルの質問に対する答えは「コンパイルでないとしてOPがリストするすべてが角度コンパイルとは何か」です。
イェルクWミッターク

これが実質的な違いではなく、命名規則について実際にどのようになっているのかについての本当に良い説明。マイクロコードに言及することでおそらく改善される可能性があります-マシンコードのレベルでさえ、あなたは「金属」ではないことを指摘します...
AakashM 2017年

1
私はどういうわけかコンパイラが何であるかを学んだことを覚えています。当時誰かが私に言ったとしたら、「コンパイラ」は「コードの翻訳者」の同義語であり、それが何のためにあるのか、なぜそれが必要なのかを知るのははるかに簡単だったでしょう。確かに、これは今日の観点からはばかげているように聞こえますが、これは、適切な人に何かを教えることからどれだけの利益が得られるかをもう一度教えてくれます。ありがとうございました。:)
codepleb 2017年

18

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

1)TypescriptをJavaScriptにトランスパイルします。これは一種の解決された問題です。彼らはただwebpackを使っていると思います。

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

その2番目のビットであるAngularコンパイラに本当に興味がある場合は、 コンパイラの作成者であるTobiasBoschがAngularConnect2016でAngularコンパイラについて説明しているのをご覧ください

ここでは、トランスパイルとコンパイルの間に少し混乱が生じていると思います。それは一種の問題ではなく、個人的な好みの問題であり、どちらもコードの表現間の変換にすぎません。しかし、私が個人的に使用する定義は、トランスパイルは同様の抽象化レベル(たとえば、typescriptからjavascript)の2つの異なる言語間で行われるのに対し、コンパイルでは抽象化レベルを下げる必要があるというものです。テンプレート、コンポーネント、パイプ、ディレクティブなどからjavascriptだけまでは、抽象化のはしごを一歩下がったものだと思います。そのため、コンパイラと呼ばれています。


1

Angularコンパイラ

Angular 4から5への最も重要な変更の1つは、コンパイラーがより速く、より徹底的に書き直されたことです。これまで、Angularアプリケーションは、Just-in-Time(JIT)コンパイルと呼ばれるものを使用していました。このコンパイルでは、アプリケーションは実行前にブラウザーで実行時にコンパイルされていました。Angular 5でのコンパイラの更新により、AOTへの移行が進み、アプリの実行時に実行されるコンパイルが少なくなるため、アプリの実行が高速化されました。Angular CLIの1.5バージョン以降、すべての本番ビルドでAOTがデフォルトで有効になります。

デプロイ用のアプリケーションを構築し、次のコマンドを実行するとします。

ng build --prod

いくつかのことが起こります:製品バージョン、ミニファイ、アセットのバンドル、ファイル名ハッシュ、ツリーシェイク、AOT ...(フラグを使用してこれを有効/無効にできます。例:aot = false)。つまり、prodフラグは、ngc(Angularコンパイラ)を使用してAOTコンパイルを実行し、ブラウザですぐに使用できる最適化されたコードを作成することで、アプリケーションの最適化されたバンドルを作成します(はい、テンプレートをプリコンパイルします))。

TypeScriptコンパイラ

TypeScriptコンパイラ、tsc、TypeScriptファイルのコンパイルを担当します。静的型などのTypeScript機能の実装を担当するのはコンパイラであり、その結果、TypeScriptキーワードと式が削除された純粋なJavaScriptが作成されます。

TypeScriptコンパイラには、トランスパイラーとタイプチェッカーの2つの主要な機能があります。コンパイラはTypeScriptをJavaScriptに変換します。ソースコードに対して次の変換を行います。

  • すべての型注釈を削除します。
  • 古いバージョンのJavaScript用に新しいJavaScript機能をコンパイルします。
  • 標準のJavaScriptではないTypeScript機能をコンパイルします。

これを呼び出すと、コンパイラーはtsconfig.jsonにロードされた構成を検索します(すべてのコンパイラー・オプションの詳細なリストとデフォルト値は、ここにあります)。

ほとんどの点で、TypeScriptコンパイラは他のコンパイラと同じように機能します。ただし、不注意を見つけることができる1つの違いがあります。デフォルトでは、コンパイラはエラーが発生した場合でもJavaScriptコードを出力し続けます。幸い、この動作はnoEmitOnError、tsconfig.jsonファイルで構成設定をtrueに設定することで無効にできます。

注意tscngcは目的が異なり、どちらかを選択することではありません。この答えは興味深いかもしれません

この回答は、以下の本の内容に基づいて作成されました

  • クロー、M。(2018)。「Angular5プロジェクト:70以上のプロジェクトを使用してシングルページWebアプリケーションを構築する方法を学ぶ」。

  • Dewey、B.、Grossnicklaus、K.、Japikse、P。(2017)「VisualStudio2017を使用したWebアプリケーションの構築:.NETCoreと最新のJavaScriptフレームワークの使用」。

  • フリーマン、A。(2019)。「エッセンシャルTypeScript:初心者からプロへ」。

  • ギヤ、P。(2018)。「TypeScriptマイクロサービス」。

  • Iskandar、A.、Chivukulu、S。(2019)「AngularとBootstrapを使用したWeb開発-第3版」。

  • ヘネシー、K。、アロラ、C。(2018)。「例によるAngular6」。

  • Jansen、R.、Wolf、I.、Vane、V。(2016)「TypeScript:最新のJavaScript開発」。

  • モハメッド、Z。(2019)。「AngularProjects」。

  • Seshadri、S。(2018)。「Angular:UpandRunning」。

  • Wilken、J。(2018)。「AngularinAction」。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.