Making AngularJS Dependency Injection Safe for Minification
Learn why AngularJS 1.x breaks after minification and how explicit array or $inject annotation preserves dependency mapping in production builds.
12 Nov 2025, 19:41 UTC

Problem: Minification Breaks AngularJS DI
When you build a legacy AngularJS 1.x application for production, JavaScript minifiers rename function parameters to shorter names (e.g., $scope becomes a). AngularJS’s dependency injector resolves services by matching those parameter names at runtime. After minification the injector can no longer find a provider named a, and the app fails with an "Unknown provider" error.
Useful takeaway: Add explicit dependency annotations so the injector reads the original service names from a string array, allowing the function parameters to be safely renamed by the minifier.
How Explicit Annotation Works
AngularJS’s $injector looks for annotation in two places:
An array where the last element is the factory function and all preceding elements are string names of dependencies.
A
$injectproperty on the factory function that contains the same string array.
When the injector sees either form, it ignores the actual parameter names and uses the strings to look up providers. This decouples the injection contract from the code that gets minified.
Worked Example: Controller with Array Annotation
// app.js
angular.module('myApp', [])
.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.load = function () {
$http.get('/api/items')
.then(function (response) {
$scope.items = response.data;
});
};
}]);
The array ['$scope', '$http', function …] tells AngularJS to inject $scope first and $http second, regardless of how the function parameters are renamed.
Alternative: Using the $inject Property
function MainCtrl($scope, $http) {
$scope.load = function () {
$http.get('/api/items')
.then(function (r) { $scope.items = r.data; });
};
}
MainCtrl.$inject = ['$scope', '$http'];
angular.module('myApp').controller('MainCtrl', MainCtrl);
Both approaches are equivalent; choose the one that matches your team’s style.
What Happens After Minification
Suppose a minifier transforms the controller to:
angular.module('myApp').controller('MainCtrl',['$scope','$http',function(a,b){a.load=function(){b.get('/api/items').then(function(c){a.items=c.data});}}]);
The parameter names a and b are shortened, but the string array still contains '$scope' and '$http'. The injector matches the strings to the correct providers, so the app works.
Limits and Common Mistakes
Manual Synchronization
Explicit annotation must stay in sync with the function signature. If you rename or reorder a parameter but forget to update the string array, the injector will wire the wrong services, leading to subtle bugs that are hard to trace.
Order Sensitivity
The array order must match the parameter order exactly. Swapping '$scope' and '$http' while keeping the function signature unchanged causes $scope to receive the $http service and vice‑versa.
ng‑strict‑di Mode
Adding ng-strict-di to the ng-app element forces AngularJS to throw an error whenever a component lacks explicit annotation. This is valuable for catching missing annotations in a build, but it will break any existing code that relies on implicit DI.
End‑of‑Life Considerations
AngularJS 1.x reached end of life in January 2022 and receives no further security patches. Use explicit annotation only when maintaining an existing codebase; plan a migration to a supported framework for new development.
Practical Verification Steps
Create a minimal module with a controller that uses array annotation (as shown above). Load the unminified version in a browser and verify that
$scope.load()fetches data.Rename the function parameters manually to simulate minification (e.g.,
function(a,b){…}) and reload the page. The controller should still work because the string array is unchanged.Enable
ng-strict-dion theng-appattribute and confirm the application boots only when every component uses explicit annotation.Run your production build through a minifier (UglifyJS, Terser, etc.) and inspect the generated code. Ensure parameter names are shortened while the string arrays remain intact, then smoke‑test the built app.
If any step fails, check the annotation array for mismatches or missing entries.
Conclusion
Explicit dependency annotation is the reliable way to keep AngularJS 1.x applications functional after minification. By declaring dependencies as strings—either via an inline array or a $inject property—you protect the injection contract from parameter renaming. Remember to keep the annotation in sync with the function signature, respect order, and consider enabling ng-strict-di in builds to catch omissions early. While this technique keeps legacy apps running, it does not change the fact that AngularJS 1.x is unsupported; treat it as a temporary measure while planning a migration.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.