-->

Angular build not working on server

2019-05-01 12:58发布

问题:

I am trying to run my AngularJS front-end on server. I am using Yeoman to build the app. I upload the very basic hello world app and I get plain HTML text withou JavaScript loaded. Console in Chrome says this:

Error: Unknown provider: aProvider <- a
    at Error (<anonymous>)
    at http://../scripts/vendor/d10639ae.angular.js:2627:15
    at Object.getService [as get] (http://../scripts/vendor/d10639ae.angular.js:2755:39)
    at http://../scripts/vendor/d10639ae.angular.js:2632:45
    at getService (http://../scripts/vendor/d10639ae.angular.js:2755:39)
    at invoke (http://../scripts/vendor/d10639ae.angular.js:2773:13)
    at Object.instantiate (http://../scripts/vendor/d10639ae.angular.js:2805:23)
    at http://../scripts/vendor/d10639ae.angular.js:4620:24
    at update (http://../scripts/vendor/d10639ae.angular.js:13692:26)
    at http://../scripts/vendor/d10639ae.angular.js:8002:24 d10639ae.angular.js:5526

Anybody experiencing the same and knows the way out?

EDIT:

'use strict';

yoAngApp.controller('MainCtrl',['$scope', '$window', function($scope, $window) {
    $scope.awesomeThings = [
        'HTML5 Boilerplate',
        'AngularJS',
        'Testacular'
    ];

    $scope.records = [{ title : 'one' }, { title : 'two' }, { title : 'three' }, { title : 'four' }];

    $scope.greet = function() {
        ($window.mockWindow || $window).alert('Hello ' + $scope.name);
    }
}]
);

回答1:

As @ŁukaszBachman suggested, you may use $inject annotation or you may use Inline Annotation if you want to:

  1. Keep your dependency annotations close to your function definitions (for better readability).
  2. Stay away from polluting global namespace.

 

app.controller('UsersController',
  [
    '$scope', 'UserService', '$location', '$routeParams',
    function($scope, User, $location, $routeParams) {
      $scope.user = User.get({id: $routeParams.id});
      ...
    }
  ]
);


回答2:

I'm pretty sure that you have used code minifier for production server, am I right?

Anyways, the folks from Angular Js made pretty clear that using minifier can mess up Dependency Injection if it's not done properly. Why this happens? Have a look:

Dependency Injection vs. Code Minifier

function MyController($scope, $log) { ... }

In the snippet above you are making use of implicit DI. Angular sees variable $scope and tries to match it with any managed dependency. In this example it will match it to the $scope object.

This, however, will not work after code minifying, as the result will look somehow like this:

function a(b, c) { ... }

Since variable and function names were minified, Angular cannot know what exactly an "a" is.

Solution

Use explicit Dependency Injection configuration.

var MyController = function($scope, $log) { ... }
MyController.$inject = ['$scope', '$log'];

In this snippet you are defining which dependencies should be resolved by attaching array of their names to special property of controller (or service) called $inject. Now Angular will know that it should resolve $scope and pass it as first parameter to MyController. Then it will resolve $log and pass it as second parameter. It's all possible because minifiers won't modify the contents of string variables.