1. ホーム
  2. angular

[解決済み] Angularのビルドと実行方法

2022-12-07 03:29:34

質問

Angularがどのようにビルドされ、舞台裏で実行されるかを学びたいだけですか?

以下は、私がこれまでに理解したことです。私が何かを見逃していたら知りたいです。

Angularのビルド方法

TypeScriptを使ってAngularアプリをコーディングした後、Angular CLIコマンドを使ってアプリをビルドします。

ng build コマンドはアプリケーションを出力ディレクトリにコンパイルし、ビルドアーチファクトは dist/ ディレクトリに保存されます。

内部処理

1. Angular CLIはWebpackを実行し、すべてのJavaScriptとCSSのコードをビルドしてバンドルします。

2. WebpackはTypeScriptローダーを呼び出し、すべての .ts ファイルを取得し、JavaScriptにトランスパイルする、つまり .js ファイルに変換し、ブラウザが理解できるようにします。

これは の投稿によると、Angularには2つのコンパイラがあるそうです。

  • ビューコンパイラ

  • モジュールコンパイラ

ビルドに関する質問

ビルドプロセスを呼び出す順序を教えてください。

Angular CLIはまずTypeScriptで書かれたAngular組み込みコンパイラを呼び出す => 次にTypeScript Transpilerを呼び出す => そしてWebpackを呼び出してバンドルして dist/ ディレクトリに格納します。

Angularの動作方法

ビルドが完了すると、アプリのコンポーネント、サービス、モジュールなどがすべて JavaScript .js ファイルに変換され、ブラウザでAngularアプリケーションを実行するために使用されます。

のステートメントは Angular Docs

  1. でブートストラップした場合 AppComponent クラス(main.ts内)でブートストラップするとき、Angularは <app-root> を探します。 index.html の中にあり、それを見つけて AppComponent のインスタンスを作成し、それを <app-root> タグの中にレンダリングします。

  2. Angularはユーザーがアプリケーション内を移動するのに合わせて、コンポーネントを作成、更新、破棄します。

ランに関する質問

しかし main.ts はブートストラッププロセスを説明するために上の文で使われていますが、Angularアプリはブートストラップされるか、JavaScriptを使って開始されるわけではありません。 .js ファイルを使って起動されるのではないでしょうか?

上記の記述はすべてJavaScriptを使ってランタイムに行われているのではないでしょうか? .js ファイルを使って実行されているのではないでしょうか?

すべてのパーツがどのように深く組み合わされているのか、誰か知っていますか?

どのように解決するのですか?

(私がAngularと言うとき、私はAngular 2+を意味し、私がAngular 1に言及している場合は明示的にangular-jsと言うでしょう)。

前置きです。それは紛らわしいです

Angular、そしておそらくより正確にはangular-cliは、ビルドプロセスに関わるJavascriptの多くのトレンドツールをマージしています。 それは少しばかり混乱につながります。

さらに混乱を招くのが、この compile という用語は、テンプレートの擬似 HTML を取って DOM 要素に変換するプロセスを指すために angular-js でよく使われました。 それはコンパイラが行うことの一部ではありますが、小さな部分の1つです。

まず第一に、Angularを動かすためにTypeScript、angular-cli、Webpackを使う必要はありません。 あなたの質問に答えるために。 単純な質問を見てみましょう:"Angularとは何ですか?"

Angular。何をするものなのでしょうか?

このセクションは議論を呼ぶかもしれません、見てみましょう。 Angularが提供するサービスの中核は、Javascript、HTML、CSSにまたがって動作する依存性注入メカニズムです。 あなたはすべての小さな断片を個別に書き、それぞれの小さな断片で他の断片を参照するためのAngularのルールに従います。 そして、Angularはそれをどうにかして一つにまとめます。

(少し)具体的に言うと

  • テンプレートは、HTML を Javascript コンポーネントに配線することを可能にします。 これにより、DOM 自体へのユーザーの入力 (ボタンのクリックなど) を Javascript コンポーネントに送り込むことができ、また Javascript コンポーネントの変数が DOM の構造と値を制御することができます。
  • Javascript クラス (Javascript コンポーネントを含む) は、依存する他の Javascript クラスのインスタンスにアクセスできる必要があります (例: 古典的な依存性注入)。 BookListComponent は BookListService のインスタンスを必要とし、BookListPolicy のインスタンスやそのようなものを必要とするかもしれません。 これらのクラスはそれぞれ異なる寿命を持ち(例えば、サービスは通常シングルトン、コンポーネントは通常シングルトンではありません)、Angularはこれらの寿命、コンポーネントの作成、依存関係の配線をすべて管理しなければなりません。
  • CSS ルールは、DOM のサブセットにのみ適用されるように読み込まれる必要がありました (コンポーネントのスタイルはそのコンポーネントにローカルです)。

注意すべき重要なことの1つは、AngularはJavascriptファイルが他のJavascriptファイルをどのように参照するかについて責任を負わないことです(例えば import キーワードなど)。 これはWebpackによって処理されます。

コンパイラは何をするのですか?

Angularが何をするのかがわかったので、コンパイラが何をするのかについて話しましょう。 私が無知なため、あまり技術的なことは避けたいと思います。 しかし、依存性注入システムでは、通常、何らかのメタデータで依存性を表現する必要があります(例えば、どのようにしてクラスが I can be injected , My lifetime is blah または You can think of me as a Component type of instance ). Javaでは、SpringはもともとXMLファイルを使ってこれを実現していました。 Javaはその後アノテーションを採用し、メタデータの表現方法として好まれるようになった。 C#ではメタデータを表現するために属性を使用します。

Javascriptはこのメタデータをビルトインで公開するための優れたメカニズムを持っていません。angular-jsはその試みを行い、悪くはなかったのですが、簡単にチェックできないルールが多く、少し混乱しました。 Angularでは、メタデータを指定する方法として2つの方法がサポートされています。 純粋なJavascriptを書き、メタデータを手動で指定する方法です。angular-jsにやや似ていて、ルールに従いつつ、余計なボイラープレート的なコードを書き続けるだけでよいのです。 あるいは、TypeScriptに切り替えることもできます。TypeScriptには、偶然にもデコレータがあります(これらの @ シンボル)があり、メタデータを表現するために使用されます。

さて、ここでようやくコンパイラにたどり着きます。 コンパイラーの仕事は、メタデータを受け取り、アプリケーションという動作する部品のシステムを作成することです。 あなたはすべての部品とすべてのメタデータに注目し、コンパイラは相互に接続された1つの大きなアプリケーションを構築します。

コンパイラはどのようにそれを行うのでしょうか。

コンパイラの動作には、ランタイムと先読みという2つの方法があります。 ここからはTypeScriptを使用していると仮定します。

  • ランタイムです。 typescriptコンパイラが実行されると、すべてのデコレータ情報が取り込まれ、デコレートされたクラス、メソッド、フィールドに付随するJavascriptコードに押し込まれます。 あなたの index.html で、あなたの main.js を参照し bootstrap メソッドを呼び出します。 そのメソッドはあなたのトップレベルモジュールに渡されます。

ブートストラップメソッドはランタイムコンパイラを起動し、 そのトップレベルモジュールへの参照を与える。 そして、ランタイムコンパイラーはそのモジュール、 そのモジュールによって参照される全てのサービス、コンポーネントなど、 関連する全てのメタデータのクロールを開始し、アプリケーションを構築します。

  • AOT。 Angularは実行時にすべての作業を行うのではなく、ビルド時にほとんどの作業を行うメカニズムを提供しています。 これはほとんど常に webpackプラグイン (これは最も人気のある、しかし最も知られていないnpmパッケージの1つであるに違いありません)を使用して行われます。 AOT は typescript のコンパイルの後に実行されるので、基本的にランタイムコンパイラと同じ入力を見ることができます。 AOT コンパイラは、ランタイムコンパイラと同様にアプリケーションを構築しますが、その後、Javascript に戻して保存されます。

ここでの利点は、コンパイル自体に必要な CPU 時間を節約できるだけでなく、アプリケーションのサイズを小さくすることができることです。

具体的な回答

Angular CLI まず、angularに組み込まれたコンパイラを呼び出します。 Typescript =>次にTypescript Transpiler =>を呼び出します。 Webpackでバンドルし、dist/ディレクトリに格納します。

いいえ、Angular CLIはWebpackを呼び出します(Angular CLIの実サービスはwebpackの設定です。 を実行すると ng build を実行しても、それは Webpack を起動するプロキシ以上のものではありません)。 WebpackはまずTypescriptコンパイラを呼び出し、次にAngularコンパイラを呼び出し(AOTを想定)、同時にコードをバンドルしています。

上記のStatementではbootstrapの説明のためにmain.tsが使用されていますが プロセスで使用されていますが、angularアプリはJavascriptの .jsファイルを使って起動するのでは?

何をおっしゃりたいのかよくわからないのですが。 main.ts は、Javascriptにトランパイルされます。 そのJavascriptには bootstrap への呼び出しが含まれ、これがAngularへの入り口となります。 このとき bootstrap が完了すると、完全なAngularアプリケーションが動作するようになります。

この投稿によると、Angularには2つのコンパイラがあるそうです。

ビューコンパイラ

モジュールコンパイラ

正直なところ、私はここで無知を主張するつもりです。 私たちのレベルでは、すべてを1つの大きなコンパイラとして考えることができると思います。

すべてのパーツがどのように深く組み合わされているのか、誰か知っていますか?

上記で納得していただけたでしょうか。

Don't @ Me: Angularは依存性注入以上のことをする

もちろん、ルーティング、ビューの構築、変更の検出、および他のすべての種類のことを行います。 コンパイラーは、ビュー構築と変更検出のための Javascript を実際に生成します。 依存性注入だけだと言ったのは嘘です。 しかし、依存性注入は中核であり、回答の残りの部分を駆動するのに十分です。

これをコンパイラーと呼ぶべきでしょうか。

おそらく多くのパースとレキシングを行い、その結果として多くのコードを生成するので、その理由からコンパイラと呼ぶことができます。

一方、コンパイラはコードを単に異なる表現に翻訳しているわけではありません。 その代わりに、多くの異なるコードの断片を取り出し、それらをより大きなシステムの消費可能な断片に編んでいるのです。 そして、ブートストラッププロセスは(必要であればコンパイルした後)それらの断片を取り、Angularのコアに差し込みます。