咕哝的贡献丑陋-安格拉Js的缩小过程



我正在完成一个网络应用程序,一切都很顺利。

我使用Grunt将我所有的.js文件连接到一个唯一的文件中,这就是我在index.html文件中用来加载代码的文件。

问题是,当我使用由grunt使用"grunt contrib uglify"任务生成的文件的.min.版本时。

当我重新加载页面时,会出现以下错误:

angular.js:38未捕获错误:[$injector:modulerr]http://errors.angularjs.org/1.5.5/$injector/modulerr?p0=myapp&p1=错误%…ogleapis.com%2Fajax%2Libs%2Angularjs%2F1.5.5%2Fangular.min.js%3A39%3A222)

我一直在谷歌上阅读这篇文章,但没有成功。

我该如何解决这个问题?

编辑

这是一个典型的文件控制器(都有相同的结构):

(function() {
  var app = angular.module("post", []);
  var controllers = {};
  controllers.postCtrl = ['$scope', '$rootScope', 'myFactory', function($scope, $rootScope, myFactory) {
      $scope.loading  = {state:false};
      $scope.filters  = $scope.filters  || myFactory.authors;
      $scope.init = function() {
          var idx = myFactory.get_author_by_index(Number($('input[name="author"]').val()));
          $scope.filterSelected = $scope.filters[idx];
          angular.element(document).ready(function () {
              angular.forEach($('div.general_page_content').find('a'), function(value, index) {
                  $(value).attr('target', "_new");
              })
              angular.forEach($('div.general_page_content').find('iframe'), function(value, index) {
                  $(value).attr("width", "100%");
              })
              angular.forEach($('div.general_page_content').find('img'), function(value, index) {
                  $(value).attr("width", "100%").css('width', '100%');
              })
              myFactory.containerResize();
          });
      }
      $rootScope.$on('loading', function(evt, value) {
          $scope.loading.state = value;
      });
      $rootScope.$on('autocomplete:focus', function(ev) {
          $scope.search_focus = true;
      });
      $rootScope.$on('autocomplete:blur', function(ev) {
          $scope.search_focus = false;
      });
      $scope.showSocialShare = function(ev) {
          $scope.url  = decodeURIComponent($('input[name="url"]').val());
          $scope.text = decodeURIComponent($('input[name="text"]').val());
          $scope.img  = decodeURIComponent($('input[name="img"]').val());
          myFactory.showSocialShare($scope, ev);
      };
      $scope.favorite_post = function(ev, id, title) {
          myFactory.favorite_post($scope, ev, id, title);
      }
      $scope.fetchPostsChange = function(selected) {
          document.location = '/blog/?author='+selected.id;
      }
      $scope.search = function(text) {
          document.location = '/blog/?search='+encodeURIComponent(text);
      }
      $scope.go_to_favorites_post = function() {
          document.location = '/blog/archive/';
      }
      $scope.init();
  }];
  app.controller(controllers);
})();

更新

我只取了两个.js文件,并对它们进行了处理,以缩小它,并检查是否出现了相同的错误。奇怪的是,只考虑两个文件,就会出现相同的错误,所以我粘贴缩小的文件,以便您能够检测出问题所在。

!function(){angular.module("myapp",["ngMaterial","ngMessages","ngStorage","toaster","ngMdIcons","lvl.services","smart-table","angularGrid","ngFileUpload","angular-timeline","header","dashboard","sidebar","autocomplete","timeline","sidebarCollection","myappFactory","objectCtrl","homeCtrl","Collections","Collection","posts","post","model","postArchive","720kb.socialshare","services","footer"]).config(function(a,b,c){a.theme("default").primaryPalette("lime").accentPalette("grey").warnPalette("red"),a.theme("darkTheme").primaryPalette("lime").accentPalette("grey").warnPalette("red").dark(),b.enabled(!1),c.get("user")})}(),function(){var a=angular.module("autocomplete",[]),b={},c={};b.autocompleteCtrl=["$http","$scope","$mdBottomSheet","$sessionStorage","myappFactory",function(a,b,c,d,e){b.init=function(){b.session=d,angular.isUndefined(b.session.advance_search)&&(b.session.advance_search={select_all:!0,show_cost:!0,show_free:!0,items:[{name:"Thingiverse",selected:!0},{name:"Youmagine",selected:!0},{name:"MyMinifactory",selected:!0},{name:"Cults 3D",selected:!0},{name:"Pinshape",selected:!0},{name:"Turbosquid",selected:!0},{name:"Shapeways",selected:!0},{name:"GrabCAD",selected:!0},{name:"CGTrader",selected:!0},{name:"Threeding",selected:!0}]})},b.querySearch=function(c){var d=c.trim();return d&&d.length>2?(b.isFetching=!0,a.get(e._myapp_link+"/api/index.php/myapp/autocomplete/"+encodeURIComponent(d)).then(function(a){return a.data})):void 0},b.collectionSearch=function(c){var d=c.trim();return d&&d.length>2?(b.isFetching=!0,a.get(e._myapp_link+"/api/index.php/myapp/collection_search/"+encodeURIComponent(d)).then(function(a){return a.data})):void 0},b.search=function(a){var c="";b.session.advance_search.show_cost&&!b.session.advance_search.show_free?c+=" free:0 ":!b.session.advance_search.show_cost&&b.session.advance_search.show_free&&(c+=" free:1 "),angular.forEach(b.session.advance_search.items,function(a,d){(b.session.advance_search.select_all||a.selected)&&(c+=" plataforma:"+a.name)}),window.location="/?search="+encodeURIComponent(a)+"&params="+Base64.encode(c)},b.go_to_collection=function(a){window.location="/collections/"+encodeURIComponent(a)},b.showAdvancedSearch=function(){c.show({templateUrl:"/advanced_search_sheet.html",controller:"ListBottomSheetCtrl"})},b.init()}],b.ListBottomSheetCtrl=["$scope","$mdBottomSheet","$sessionStorage","myappFactory",function(a,b,c,d){a.session=c,a.toggle_all_sites=function(){a.session.advance_search.select_all=!a.session.advance_search.select_all,a.session.advance_search.select_all&&angular.forEach(a.session.advance_search.items,function(a,b){a.selected=!0})},a.toggle_advance_search=function(b){if(a.session.advance_search.select_all)a.session.advance_search.items[b].selected=!0,d.showMessage({msg:"Uncheck 'All repositories' first!"});else if(a.session.advance_search.items[b].selected=!a.session.advance_search.items[b].selected,!a.session.advance_search.items[b].selected){var c=0;angular.forEach(a.session.advance_search.items,function(a,b){a.selected&&++c}),c||(a.session.advance_search.items[b].selected=!0,d.showMessage({msg:"There must be at least 1 respository selected!"}))}},a.free_cost_checked=function(b){var c="cost"==b?!a.session.advance_search.show_cost:!a.session.advance_search.show_free;c?"cost"==b?a.session.advance_search.show_cost=!0:a.session.advance_search.show_free=!0:"cost"==b?a.session.advance_search.show_free?a.session.advance_search.show_cost=!1:d.showMessage({msg:"Free and Price cannot be unchecked!"}):"free"==b&&(a.session.advance_search.show_cost?a.session.advance_search.show_free=!1:d.showMessage({msg:"Free and Price cannot be unchecked!"}))}}],c.myEnter=function(){return function(a,b,c){b.bind("keydown keypress",function(b){13===b.which&&(a.$apply(function(){a.search(a.searchText)}),b.preventDefault())})}},c.onBlur=["$rootScope","$mdUtil","$timeout",function(a,b,c){return{require:"^mdAutocomplete",link:function(d,e,f,g){c(function(){var c=(e.find("input"),e[0],g.blur),h=g.focus;g.blur=function(){c.call(g),b.nextTick(function(){a.$broadcast("autocomplete:blur"),d.$eval(f.mdBlur,{$mdAutocomplete:g})})},g.focus=function(){h.call(g),b.nextTick(function(){a.$broadcast("autocomplete:focus"),d.$eval(f.mdFocus,{$mdAutocomplete:g})})}})}}}],a.controller(b).directive(c)}();

正如你在谷歌上发现的那样,这个错误取决于Variable Manglinghttps://github.com/gruntjs/grunt-contrib-uglify#mangle.

因此,当您将$rootScope修改为a时,当然,角度依赖注入无法解决它:

angular
  .module('test', [])
  .run(function($injector) {
    console.log(
      "$rootScope exists?", 
      $injector.has('$rootScope')
    );
    
    try {
      // mangle $rootscope => a
      $injector.get('a');
    } catch(e) { 
      console.log('a exists?', e.message); 
    }
    
  })
;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
<section ng-app="test"></section>

有很多方法可以解决这个问题:

  1. 禁用变量Mangling(不是一个好方法,但却是一个解决方案)
  2. 始终使用Angular DI Annotation

    a。阵列表示法:someModule.run(["$rootScope", function(a) {}]);

    b$注入属性:runFn.$inject = ['$rootScope']; function runFn(a) {}; someModule.run(runFn);

  3. 使用在生成时进行注释的ngAnnotate。我建议你选择这个选项,因为你不需要关心注释。。。

重要事项:始终以angular strict di模式运行代码,这使您有机会控制每个注释问题。

如果缩小,则必须命名每个模块的注入。所以在你可能有之前:

app.factory('myFactory', function($route) {
});

现在你必须命名/声明它们,否则棱角分明的人不知道该注入什么:

app.factory('myFactory', ['$route', function($route) {
}]);

为什么

最小化将一切都变成了小变量。所以我们的工厂变成了:

app.factory('myFactory', function(a) {
      a.<functioncall>
});

Angular不知道"a"是什么,所以必须告诉:

app.factory('myFactory', ['$route', function(a) {
      a.<functioncall>
}]);

所以它现在知道了,a=$route等等。

最新更新