1. ホーム
  2. angularjs

[解決済み] 「不明なプロバイダ:aProvider <- a" オリジナルのプロバイダを見つけるにはどうしたらいいですか?

2022-12-23 10:40:26

質問

AngularJSアプリケーションのminify(UglifyJSを通して)バージョンをロードしているとき、コンソールに以下のエラーが表示されます。

Unknown provider: aProvider <- a

さて、私はこれが変数名のマングリングによるものであることを理解しています。マングリングされていないバージョンは問題なく動作します。しかし、私は を実行します。 は変数名のマングリングを利用したいと思います。それはJS出力ファイルのサイズを劇的に減らすからです。

そのため、私たちは ngmin を使用していますが、過去にうまく機能したにもかかわらず、この問題を解決していないようです。

そこで、この問題をデバッグするために、私は、uglify grunt タスクでソース マップを有効にしました。それらは適切に生成され、Chrome は行います。 はサーバーからマップをロードします。しかし、プロバイダーの元の名前が表示されるはずだという印象を受けたにもかかわらず、まだ同じ役に立たないエラー メッセージが表示されます。

どのプロバイダーが問題なのかを知るために、Chrome にソース マップを使用させるにはどうしたらよいでしょうか、あるいは、別の方法でプロバイダーを見つけるにはどうしたらよいでしょうか。

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

この問題を引き起こしたソース コードの場所をどのようにして見つけることができたのか、まだ知りたいところですが、その後、問題を手動で見つけることができました。

グローバルスコープで宣言されたコントローラ関数があり、代わりに .controller() の呼び出しではなく、グローバルスコープで宣言されたコントローラ関数がありました。

というようなものがあったんですね。

function SomeController( $scope, i18n ) { /* ... */ }

これはAngularJSでは問題なく動作しますが、manglingで正しく動作させるために、次のように変更する必要がありました。

var applicationModule = angular.module( "example" );
function SomeController( $scope, i18n ) { /* ... */ }
applicationModule.controller( "SomeController", [ "$scope", "i18n", SomeController ] );

さらにテストした結果、実はもっと多くのコントローラで問題が発生していることがわかりました。これは、それらのすべてのソースを見つける方法です。 手動で :

まず、uglifyのオプションで出力の美化を有効にすることがかなり重要だと考えています。私たちのgruntタスクでは、それは意味しました。

options : {
    beautify : true,
    mangle   : true
}

次に、DevToolsを開いたまま、ChromeでプロジェクトのWebサイトを開いてみました。その結果、以下のようなエラーがログに残りました。

コールトレースで注目しているのは、矢印でマークしたメソッドです。これは providerInjectorinjector.js . それが例外を投げるところにブレークポイントを置きたいと思うでしょう。

これでアプリケーションを再実行すると、ブレークポイントがヒットし、コールスタックをジャンプアップすることができます。このとき invoke の中に injector.js という文字列から認識されます。

locals パラメータ(マングルで d に変更) は、ソースのどのオブジェクトが問題であるかについて、かなり良いアイデアを提供します。

簡単に言うと grep のインスタンスが多数見つかりました。 modalInstance が見つかりましたが、そこから先は、ソースのこの場所を見つけるのは簡単でした。

var ModalCreateEditMeetingController = function( $scope, $modalInstance ) {
};

に変更する必要があります。

var ModalCreateEditMeetingController = [ "$scope", "$modalInstance", function( $scope, $modalInstance ) {
} ];

変数が有用な情報を保持していない場合、さらにスタックの上にジャンプすることも可能で、その場合は invoke の呼び出しにぶつかるはずで、そこには追加のヒントがあるはずです。

再発防止策

さて、問題が見つかったところで、今後このようなことが起こらないようにするための最善の方法について述べておきたいと思います。

明らかに、あなたは単に インライン配列アノテーション を使うこともできますし、(好みにもよりますが) $inject プロパティ・アノテーション を作成し、将来的に忘れないようにするだけです。その場合、必ず 厳密な依存性注入モード を有効にし、このようなエラーを早期に発見できるようにしてください。

気をつけましょう。Angular Batarangはアノテーションされていないコードをあなたのコードに注入するからです(悪いBatarangです!)。

または にすることもできます。 ng-annotate を利用してください。そうすることで、この分野での間違いの可能性を大きく取り除くことができますので、ぜひそうすることをお勧めします。

  • DI アノテーションがない
  • DIアノテーションが未完成
  • DIアノテーションの順序が正しくない

アノテーションを最新の状態に保つのは単に面倒なことで、自動的にできるのであればやる必要はないはずです。

でビルドプロセスにうまく統合されるはずです。 grunt-ng-annotate gulp-ng-annotate(ガルプ・ング・アノテート .