code obfuscation breaks dependency injection in AngularJS 0.10.5

1,060 views
Skip to first unread message

Daniel Nelson

unread,
Jan 3, 2012, 1:01:15 PM1/3/12
to ang...@googlegroups.com
I finally figured out why obfuscation is breaking AngularJS. Even with
explicit dependency injection, the injector calls
inferInjectionArgs(), which infers the dependencies based on function
_parameter names_. Parameter names are usually safe to obfuscate
because they have a local scope.

It seems to me that this means that the dependency inferrer is by its
nature incompatible with obfuscation. Will it be possible to disable
inferred dependency injection (or have it disabled by default, or have
it disabled if explicit dependency declaration is present)?

Here is an example from my code:

Given this service:

(function() {
angular.service('Card', function($resource) {
return $resource('/payment/card', {}, {
get: {
method: 'GET',
isArray: false
}
});
});
}).call(this);

And this controller:

(function() {
this.SubscriptionCtrl = function(Card, $xhr) {
var scope;
scope = this;

...

};
};
this.SubscriptionCtrl.$inject = ['Card', '$xhr'];
}).call(this);


Which is obfuscated (in part), to this:

function(){this.SubscriptionCtrl=function(a,b)...
// Note that the "Card" parameter is now "a"


From AngularJS:

function injector(value){
if (!(value in instanceCache)) {
var factory = factories[value];
if (!factory) throw Error("Unknown provider for '"+value+"'.");
inferInjectionArgs(factory);
instanceCache[value] = invoke(factoryScope, factory);
}
return instanceCache[value];
}

function inferInjectionArgs(fn) {
assertArgFn(fn);
if (!fn.$inject) {
var args = fn.$inject = [];
var fnText = fn.toString().replace(STRIP_COMMENTS, '');


///////////////Matching the args, which have been obfuscated//////////

var argDecl = fnText.match(FN_ARGS);
forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
arg.replace(FN_ARG, function(all, name){
args.push(name);
});
});
}
return fn.$inject;
}

Vojta Jina

unread,
Jan 3, 2012, 8:20:04 PM1/3/12
to ang...@googlegroups.com
You have to specify dependencies with $inject property, otherwise DI has no chance to know what to inject...

angular.service('Card', function($resource) {
  // your code
}, {$inject: ['$resource']});

V.

Daniel Nelson

unread,
Jan 3, 2012, 9:29:35 PM1/3/12
to ang...@googlegroups.com
Excellent. Thank you Vojta!
Message has been deleted

Ricardo Gonzales

unread,
Jul 14, 2015, 4:23:49 PM7/14/15
to ang...@googlegroups.com
What did you use to obfuscate angular projects? I'm searching over the internet and everything is about minification and "do not obfuscate your code" :( Hope you can help me.
Reply all
Reply to author
Forward
0 new messages