2014年8月25日月曜日

angular1.3から追加されるng-strict-diを使ってminifyに強くする。

angular1.3から追加される(そう)strict-diモードについて覚書

ng-strict-diとは?

ng-strict-diとはng-app directive と一緒に付加することで、 injectorをstrict-diモードにすることができるng-appのオプションです。

何を解決するか

strict-diモードを利用することで、Dependency Annotationのつけ忘れを防ぎます。

strict-diモードとangularのminify問題

angularのDependency Annotation

AngularJSのDIには大きく分けて3つの注釈が存在します。 AngularJSではこの注釈(annotation)を利用して名前解決をし、Service等のDIを行っています。
  • functionのパラメータ名による暗黙的な注釈
  • $injectプロパティを利用した注釈
  • inline arrayを利用した注釈

functionのパラメータ名による暗黙的な注釈

パラメータ名による暗黙的な注釈は以下のようにパラメータ名を利用してDIを行います。
function MyController($scope) {

} //angularは$scopeという変数名を利用しscopeオブジェクトを代入する

$injectプロパティを利用した注釈

$injectプロパティは注入対象に対してstring arrayとともに付加することで、 名前解決をし、代入を行います。
var MyController = function(renamed$scope, renamedGreeter) {
  ...
}
MyController['$inject'] = ['$scope', 'greeter']; //renamed$scopeにはscopeオブジェクトが代入される

inline arrayを利用した注釈

inline arrayは注入対象をangularに登録する際に一緒に指定する方法です。
someModule.factory('greeter', ['$window', function(renamed$window) {
  // ...
}]);

暗黙的な注釈の問題点

一見暗黙的な代入は記述量も少なく便利なのですが一つ大きな問題があります。 それはminify時に変数名が変わる可能性がある(と言うよりだいたい変わる)点です。
minify前
function MyController($scope) {

} //angularは$scopeという変数名を利用しscopeオブジェクトを代入する
minify後
function A(a) {

} //minifyにより変数名が変わってしまう
このため、minifyをする予定がある場合は後半二つの明示的に注釈する方法が一般的に取られます。 ただ確実にこの注釈を行っているかチェックを行う方法はありません。 というかよく忘れます。

strict-diモード

これらの問題を解決するのがstrict-diモードっぽいです。 strct-diモードはng-appが付いているタグにng-strict-di属性を付けることでstrict-diモードになります。
  <body ng-app="ngStrictTestApp" ng-strict-di>
この状態で暗黙的な注釈を利用している箇所があると以下の様なJSエラーが発生します。
Uncaught Error: [$injector:modulerr] Failed to instantiate module ngStrictTestApp due to:
Error: [$injector:strictdi] function($routeProvider) is not using explicit annotation and cannot be invoked in strict mode
http://errors.angularjs.org/1.3......2) 
これで付け忘れることはなくなりますね。

まとめ

ng-strict-diはngAnnotationのことを調べている時に気が付きました。 よく明示的な指定を忘れて、minifyしてエラーになることが多いので指定しておいて損はない気がしますね。
ただし、最初にも書きましたがAngularJS 1.3からの機能っぽいです。

0 件のコメント:

コメントを投稿