Angularの構築と実行方法


84

Angularがどのように構築され、舞台裏で実行されるかを知りたいだけですか?

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

Angularの構築方法

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

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

内部プロセス

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

2. 次に、WebpackはTypeScriptローダーを呼び出します。TypeScriptローダー.tsはAngularプロジェクト内のすべてのファイルをフェッチし、それらをJavaScript、つまり.jsブラウザーが理解できるファイルに変換します。

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

  • コンパイラの表示

  • モジュールコンパイラ

ビルドに関する質問

ビルドプロセスを呼び出すシーケンスは何ですか?

Angular CLIは、最初にTypeScript =>で記述されたAngular組み込みコンパイラを呼び出し、次にTypeScript Transpiler =>を呼び出し、次にWebpackを呼び出してディレクトリにバンドルして保存しdist/ます。

Angularの実行方法

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

内の文角度ドキュメント

  1. あなたとブートストラップするときAppComponentのために(main.tsで)クラス、角度ルックス<app-root>index.html、それを見つけAppComponentのインスタンスをインスタンス化し、内部でそれをレンダリング<app-root>タグ。

  2. Angularは、ユーザーがアプリケーション内を移動するときにコンポーネントを作成、更新、および破棄します。

ランニングに関する質問

が、main.ts角度のアプリは、ブートストラップやJavaScriptの使用開始されていないブートストラッププロセスを説明するために上の文で使用されている.jsファイルは?

上記のすべてのステートメントは、JavaScript.jsファイルを使用して実行時に実行されませんか?

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

回答:


89

(私が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 injectedMy lifetime is blahまたはYou can think of me as a Component type of instance)。Javaでは、SpringはもともとXMLファイルでこれを行いました。Javaは後に注釈を採用し、それらはメタデータを表現するための好ましい方法になりました。C#は、属性を使用してメタデータを表現します。

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

これが、最終的にコンパイラーに到達できる場所です。コンパイラーの仕事は、そのメタデータを取得して、アプリケーションである作業部分のシステムを作成することです。すべての部分とすべてのメタデータに焦点を合わせ、コンパイラーは1つの大きな相互接続されたアプリケーションを構築します。

コンパイラはどのようにそれを行いますか?

コンパイラーが機能する方法には、実行時と事前の2つがあります。ここからは、TypeScriptを使用していると仮定します。

  • ランタイム: typescriptコンパイラが実行されると、すべてのデコレータ情報が取得され、デコレートされたクラス、メソッド、およびフィールドにアタッチされたJavascriptコードに格納されます。あなたの中でindex.htmlあなたmain.jsbootstrapメソッドを呼び出すあなたを参照します。そのメソッドは、最上位モジュールに渡されます。

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

  • AOT:実行時にすべての作業を行うのではなく、Angularはビルド時にほとんどの作業を行うためのメカニズムを提供しています。これはほとんどの場合、webpackプラグインを使用し行われます(これは最も人気がありますが、最も知られていないnpmパッケージの1つである必要があります)。タイプスクリプトのコンパイルが実行された後に実行されるため、ランタイムコンパイラと基本的に同じ入力が表示されます。AOTコンパイラは、ランタイムコンパイラと同じようにアプリケーションを構築しますが、それをJavascriptに保存し直します。

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

具体的な回答

Angular CLIは、最初にTypescript =>で記述されたangular組み込みコンパイラを呼び出し、次にTypescript Transpiler =>を呼び出し、次にWebpackを呼び出してdist /ディレクトリにバンドルして保存します。

いいえ。AngularCLIはWebpackを呼び出します(Angular CLIの実際のサービスはwebpackの構成です。実行ng buildすると、Webpackを起動するためのプロキシにすぎません)。Webpackは、最初にTypescriptコンパイラを呼び出し、次にAngularコンパイラ(AOTを想定)を呼び出し、同時にコードをバンドルします。

main.tsはブートストラッププロセスを説明するために上記のステートメントで使用されていますが、Angularアプリはブートストラップされていないか、Javascript .jsファイルを使用して開始されていませんか?

私はあなたがここで何を求めているのか完全にはわかりません。 main.tsJavascriptに変換されます。そのJavascriptには、bootstrapAngularへのエントリポイントである呼び出しが含まれます。ときbootstrapに行われ、あなたの全角度のアプリケーションを実行しています。

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

コンパイラの表示

モジュールコンパイラ

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

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

上記がこれを満足させたことを願っています。

@ Meしないでください:Angularは依存性注入以上のことをします

承知しました。ルーティング、ビューの構築、変更の検出など、あらゆる種類の処理を実行します。コンパイラーは、ビューの構築と変更の検出のために実際にJavascriptを生成します。依存性注入だと言ったら嘘をついた。ただし、依存性注入は核心であり、残りの答えを推進するのに十分です。

それをコンパイラと呼ぶべきですか?

それはおそらく多くの構文解析と字句解析を行い、結果として間違いなく多くのコードを生成するので、その理由でそれをコンパイラと呼ぶことができます。

一方、それは実際にはコードを単に異なる表現に変換しているわけではありません。代わりに、さまざまなコードを取り込んで、それらをより大きなシステムの消費可能な部分に織り込みます。次に、ブートストラッププロセスは(必要に応じてコンパイルした後)それらの部分を取得し、Angularコアに接続します。


詳細な回答ありがとうございます。あなたの答えを受け入れる前に、私はあなたのステートメントThe compiler does actually generate Javascript`にビューの構築と変更の検出について疑問を持っています。`それは嘘ではありません。それはコンパイラが行うことではありませんか?そしてangularは依存性注入を行います。
shaijut 2018

1
うん、ごめん。私が言及した嘘は、「Angularが提供するサービスは、依存性注入メカニズムです」というものでした。Angularはそれを実行する一方で、それがすべてではなく、コンパイラーもすべて実行するわけではないからです。
ペース

Angularが、コンポーネント、ディレクティブ、サービスなどの機能を備えた新しい「言語」として省略されている場合。コンパイラと呼ぶことができます。Angular言語を生のjsとhtmlに準拠させます。
クリス・バオ

10

最初から始めましょう。

私のアプリケーションでは、からアプリケーションを直接実行しますWebpack

アプリケーションをビルドして実行するには、webpack-- progressおよびwebpack-dev-server--inlineコマンドを使用します。これは次のように記述されてpackage.jsonいます。

"scripts": {
    "serve": "webpack-dev-server --inline ",
    "build": "webpack --progress"

  }

webpack --progressコマンドを実行すると、webpack.config.jsファイルの読み取りが開始され、次のようにエントリポイントが見つかります。

module.exports = {
    devtool: 'source-map',
    entry: './src/main.ts',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.ts$/,
                loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
                exclude: [/\.(spec|e2e)\.ts$/]
            },
            /* Embed files. */
            {
                test: /\.(html|css)$/,
                loader: 'raw-loader',
                exclude: /\.async\.(html|css)$/
            },
            /* Async loading. */
            {
                test: /\.async\.(html|css)$/,
                loaders: ['file?name=[name].[hash].[ext]', 'extract']
            },
        ]
    },
    resolve: {
        extensions: ['.ts', '.js']
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
}   

次に、すべてのTypescriptファイルを読み取り、tsconfig.jsonファイルで宣言されたルールに基づいてコンパイルし、それぞれに変換します。.jsファイルとマップファイルにます。

コンパイルエラーなしで実行するとbundle.jsWebpack出力セクションで宣言した名前のファイルが作成されます。

それでは、ローダーを使用する理由を説明しましょう。

素晴らしい-typescriptです-ローダー、angular2のテンプレートローダは、 私たちは、コンパイルするには、これらのローダーを使用Typescriptして宣言したベース上のファイルtsconfig.jsonのファイルとangular2テンプレートローダを検索templateUrlし、styleUrls角度2コンポーネントメタデータの宣言の内部を、対応するとのパスを置き換えますステートメントが必要です。

resolve: {
        extensions: ['.ts', '.js']
    }

上記の解決セクションを使用して、ファイルWebpackに変換するTypescriptように指示しJavaScriptます

plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]

プラグインセクションは、サードパーティのフレームワークまたはファイルを挿入するために使用されます。私のコードでは、これを使用してindex.html宛先フォルダーを挿入しています。

 devtool: 'source-map',

上記の行はTypescript、ブラウザでファイルを表示し、開発者コードで主に使用されるデバッグに使用されます。

 loader: 'raw-loader'

上記raw-loader.html.cssファイルをロードし、それらを一緒にバンドルするために使用されますTypescriptます。

最後にwebpack-dev-server--inlineを実行すると、独自のサーバーが作成され、に記載されているパスとしてアプリケーションが起動します。web-pack.config.js宛先フォルダーとエントリポイントを指定ファイルにます。

Angular2エントリほとんどのアプリケーションのポイントですmain.ts我々は、例えば(app.module)の初期ブートストラップ・モジュールに言及ここで、このモジュールは、すべての指令、サービス、モジュール、コンポーネント、アプリケーション全体のルーティング実装として、完全なアプリケーション情報を含みます。

注: 多くの人index.htmlは、どこにも言及していなくても、なぜアプリケーションを起動するだけなのか疑問に思っています。答えは、Webpackserveコマンドを実行すると、独自のサーブが作成されindex.html、デフォルトのページについて言及していない場合はデフォルトでロードされます。

与えられた情報が一部の人々の助けになることを願っています。


1
あなたが説明しようとしたことに感謝します、あなたがより明確な連続した方法で説明することができればそれはより良いでしょう。だからあなたはアプリAngular CLIを構築するために使用せず、どのように直接Angular使用Webpackしますか?
shaijut 2018年

5

Angularはどのように構築されますか?

Angular CLI呼び出しWebpackWebpackヒット.ts、それはそれをオフに渡すファイルTypeScriptにコンパイル出力トランス持つコンパイラAngularのテンプレートを

したがって、ビルドシーケンスは次のとおりです。

Angular CLI=> Webpack=>TypeScriptコンパイラ=>コンパイラはコンパイル時にコンパイラをTypeScript呼び出しAngularます。

Angularはどのように実行されますか?

AngularJavascriptファイルを使用してブートストラップおよび実行します。

実際、ブートストラッププロセスは実行時であり、ブラウザを開く前に発生します。これで次の質問に移ります。

では、ブートストラッププロセスがJavascriptファイルで発生する場合、Angularドキュメントがmain.tsTypeScriptファイルを使用してブートストラッププロセスを説明するのはなぜですか?

Angular.tsそれがソースなので、ドキュメントはファイルについて話します。

これは簡単な答えです。誰かが深く答えることができれば感謝します。

チャットで私の質問に答えてくれたクレジットは@Toxicableに送られます。


2

この答えには遅れるかもしれませんが、最近、このトピックについて非常に良い話がありました。これは、初心者の視点から始まり、深く掘り下げられます。このスレッドの誤った情報を私の言葉で要約したり指摘したりする代わりに、Kara Ericksonのビデオをリンクします:Angularのしくみ

彼女はAngularフレームワークの技術リーダーであり、次の点について非常に優れたプレゼンテーションを行っています。

  • Angularフレームワークの主要部分は何ですか
  • コンパイラはどのように機能し、何を生成しますか
  • 「コンポーネント定義」とは
  • アプリケーションブートストラップとは何ですか、どのように機能しますか

1
貢献していただきありがとうございます:)、感謝します。
shaijut

1

では、ブートストラッププロセスがJavascriptファイルで発生する場合、AngularDocsがmain.tsTypeScriptファイルを使用してブートストラッププロセスを説明するのはなぜですか?

これは、発行されng buildたmain.tsの変換された.jsバージョンの一部であり、まだ醜く縮小されていません。初心者がこのコードをどのように理解することを期待しますか?それほど複雑に見えませんか?

Object(__WEBPACK_IMPORTED_MODULE_1__angular_platform_browser_dynamic__["a" /* platformBrowserDynamic */])().bootstrapModule(__WEBPACK_IMPORTED_MODULE_2__app_app_module__["a" /* AppModule */])
    .catch(function (err) { return console.log(err); });

またng build --prod --build-optimizer、コードを最適化するためにコードを醜くし、最小化することで、生成されたバンドルはコンパクトで、ビット読み取り不可能な形式になっています。

webpackJsonp([1],{0:function(t,e,n){t.exports=n("cDNt")},"1j/l":function(t,e,n){"use strict";n.d(e,"a",function(){return r});var r=Array.isArray||function(t){return t&&"number"==typeof t.length}},"2kLc

main.tsファイルは人間が読める形式でわかりやすいのに対し、angular.ioはmain.tsを使用してAngularアプリケーションのブートストラッププロセスを説明します。Angular:なぜTypeScriptなのか?これとは別に、もしあなたがそのような素晴らしいフレームワークの作者であったなら、あなたのフレームワークを人気がありユーザーフレンドリーにするためにどのようなアプローチを使用したでしょうか?複雑な説明ではなく、明確で簡潔な説明をしてみませんか?私はangular.ioのドキュメントに詳細な説明がなく、それはあまり素晴らしいものではないことに同意しますが、私が見た限りでは、彼らはそれをより良くするために懸命に努力しています。


1

Angular 9+はAOT(Ahead of Time Compilation)を使用します。つまり、コンポーネント(.ts + .html + .css)、モジュール(.ts)などのさまざまなファイルに散在するすべてのビットを取得し、実行時にダウンロードされるブラウザーで理解可能なJavaScriptを構築します。ブラウザによって実行されます。

Angular 9より前は、ブラウザーの要求に応じてコードがコンパイルされたのはJIT(Just in time Compilation)でした。

詳細については、Angular AOTDocumentaitonを参照してください。

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