web-dev-qa-db-ja.com

node_modulesのAngular2とTypeScriptのインポート

非常にシンプルな「hello world」Angular2アプリがありました。また、私の開発プロジェクトと私の春のバックエンドの最終的な展開フォルダーとの間で異なるディレクトリ構造を使用するという、明らかに不合理な決定を下しました。

この違いのため、TypeScriptのインポートに問題があり、ブラウザーで実際のアプリを開こうとすると、この行で404エラー(/ angular2/coreライブラリが見つかりません)が発生しました。

import {Component, View} from 'angular2/core';

要するに、すべてを機能させるために/ appフォルダーを追加し直しましたが、インポートステートメントを次のように変更しました。

import {Component, View} from '../node_modules/angular2/core';

ただし、これは奇妙な動作を引き起こすことが判明しました。何らかの理由で、ライブラリパスで../node_modulesを指定すると、JSはajax呼び出しを使用してすべてのAngular2ファイルを実際にロードし、npm_modules/angular2/フォルダーから個々のファイルを取得します。 HTMLヘッダー:

<script src="/node_modules/angular2/bundles/angular2.dev.js"></script>

何が起こっているのかがついにわかったとき、importステートメントを元に戻しました

import {Component, View} from 'angular2/core';

そしてそれはすべて働いた。 Angular2は上記のスクリプトタグから完全にロードされるようになり、追加のajax呼び出しによってロードされるファイルはありませんでした。

誰かがこれを引き起こしているものを説明できますか?私はそれが正常な動作であると仮定しますが、インポートがどのように機能するか、そしてより詳細なパスを指定することがそのような違いをもたらす理由を理解していません。

36
RVP

TypeScriptのimportルールは、node.jsと同じ規則に従います。インポートがドットで始まる場合:

import {Something} from './some/path';

次に、インポートを宣言するファイルからの相対パスとして扱われます。ただし、絶対パスの場合:

import {Component} from 'angular2/core';

次に、外部モジュールであると想定されるため、TypeScriptはpackage.jsonファイルを探してツリーをたどり、node_modulesフォルダーに移動して、インポートと同じ名前のフォルダーを見つけます。次に、モジュールのpackage.jsonでメイン.d.tsまたは.tsファイルを探し、それをロードしますor指定されたものと同じ名前のファイルまたはindex.d.tsまたはindex.tsファイルを探します。

書き出すと複雑なように見えますが、まだいくつかの例外があります...しかし、全体として、以前にnode.jsを使用したことがある場合、これはまったく同じように動作するはずです。

注意すべきことの1つは、このように機能するタイピング解決のために設定する必要があるTypeScriptコンパイラオプションがあることです。

tsconfig.json

"moduleResolution": "node"

ここで、質問の2番目の部分は、ajax呼び出しを使用せずにこれをどのようにロードするかです。これはSystem.jsの機能です。 index.htmlファイルにロードされるスクリプトタグは、angular2バンドルをシステムに登録するバンドルをインポートします。これが発生すると、システムはこれらのファイルを認識し、それらを参照に正しく割り当てます。これはかなり深いトピックですが、多くの情報が systemjs または systemjs-builder のREADMEにあります。

58
SnareChops