加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs – 运行concat / uglify后的角度“状态已定义”错误

发布时间:2020-12-17 09:29:07 所属栏目:安全 来源:网络整理
导读:我正在开发一个AngularJS应用程序.要在生产中发送代码,我正在使用此Grunt配置/任务: grunt.registerTask( 'compile',[ 'sass:compile','copy:compile_assets','ngAnnotate','concat:compile_js','uglify','index:compile' ]); 调试真的很难,对于那些已经遇
我正在开发一个AngularJS应用程序.要在生产中发送代码,我正在使用此Grunt配置/任务:
grunt.registerTask( 'compile',[
    'sass:compile','copy:compile_assets','ngAnnotate','concat:compile_js','uglify','index:compile'
  ]);

调试真的很难,对于那些已经遇到过这些问题并且可以指向某个方向的人来说,这是一个问题.

我的主要模块包括那些子模块:

angular
  .module('controlcenter',[
    'ui.router','ui.bootstrap','templates-app','templates-common','authentication','api','reports','interceptors','controlcenter.websites','controlcenter.users','controlcenter.campaigns','controlcenter.reports','controlcenter.login'
  ])
  .run(run);

我得到的错误如下:

Uncaught Error: [$injector:modulerr] Failed to instantiate module controlcenter due to:
Error: [$injector:modulerr] Failed to instantiate module controlcenter.websites due to:
Error: State 'websites'' is already defined

If I remove the websites module,I get the same error for
controlcenter.users.

我正在使用ui-router来处理应用程序内的路由.

在我的构建过程(用于集成测试)之后,一切正常:

grunt.registerTask( 'build',[
    'clean','html2js','jshint','sass:build','concat:build_css','copy:build_app_assets','copy:build_vendor_assets','copy:build_appjs','copy:build_vendorjs','copy:build_vendorcss','index:build','karmaconfig','karma:continuous'
  ]);

那么也许ngAnnotate或者concat / uglify在这里做了奇怪的事情?

更新1:
它与我的模块配置有关.这是代码:

angular
  .module('controlcenter.websites',[
      'ui.router'
    ]
  )
  .config(config);

config.$inject = ['$stateProvider'];

function config($stateProvider) {
  $stateProvider.state( 'websites',{
    url: '/websites',views: {
      "main": {
        controller: 'WebsitesController',templateUrl: 'websites/websites.tpl.html'
      }
    }
  });
}

>当我将状态名称更改为websites_2时,我收到错误
‘sites_2已定义’.
>当我完全删除模块时,下一个模块在配置文件中存在同样的问题.结构错了吗?

更新2:

The problem seems concat related.

它需要每个JS文件并将其一个接一个地添加到一个更大的文件中.我的所有模块都在最后.最后一个模块始终存在“已定义状态”的问题.所以这不仅仅是相互附加的模块的顺序,它还有一些东西……

更新3:
我在gist中放置了我的代码(我已经排除了每个控制器代码和函数,只是脚手架).这是我编译过程之后的结果,没有弄清楚它.

问题:

您有多个文件包含配置模块的配置功能,如下所示:

angular
    .module('controlcenter.websites',[])
    .config(config);

function config() {
    // ...
}

问题是,在连接所有文件之后,最终会得到一个带有多个config声明的大文件.由于JavaScript的变量提升,所有声明都被移到顶部,只评估它们中的最后一个,这个是:

function config($stateProvider) {
  $stateProvider.state( 'websites',templateUrl: 'websites/overview/websites.tpl.html'
      }
    },data : {requiresLogin : true }
  });
}

因此,每次你.config(config)一个模块时,你都告诉Angular用你的特定配置函数配置你的模块,这意味着它会多次执行并尝试不止一次地定义状态网站.

解:

使用闭包来包装每个JavaScript文件代码.这样您就可以避免多次声明变量/函数:

(function (angular) {

    'use strict';

    angular
      .module('controlcenter.website.details',['ui.router'])
      .config(config);

    config.$inject = ['$stateProvider'];

    function config($stateProvider) {
      $stateProvider
        .state( 'websiteDetails',{
          url: '/websiteDetails/:id',views: {
            "main": {
              controller: 'WebsiteDetailsController',templateUrl: 'websites/details/website.details.tpl.html'
            }
          },data : {requiresLogin : true }
        })

        .state( 'websiteDetails.categories',{
          url: '/categories',views: {
            "detailsContent": {
              templateUrl: 'websites/details/website.details.categories.tpl.html'
            }
          },data : {requiresLogin : true }
        })
        ;
    }
})(window.angular);

编辑:

>我强烈建议您将文件包装成闭包.但是,如果您仍然不想这样做,可以根据各自的模块命名您的功能.这样,controlcenter.website.details的配置功能将成为controlcenterWebsiteDetailsConfig.另一个选择是在构建阶段使用grunt-wrap包装代码.
> window.angular和closures:这是我喜欢在我的代码上使用的一种技术,当我要去uglify它时.通过将代码包装到闭包中并为其提供一个名为angular的参数,其实际值为window.angular,您实际上是在创建一个可以被uglified的变量.这段代码,例如:

(function (angular) {
    // You could also declare a variable,instead of a closure parameter:
    // var angular = window.angular;

    angular.module('app',['controllers']);
    angular.module('controllers',[]);
    // ...
})(window.angular);

可以很容易地对此进行修改(注意每个对angular的引用都被a替换):

!function(a){a.module("app",["controllers"]),a.module("controllers",[])}(window.angular);

另一方面,这是一个未打包的代码片段:

angular.module('app',['controllers']);
angular.module('controllers',[]);

会成为:

angular.module("app",angular.module("controllers",[]);

有关闭合的更多信息,请查看this post和this post.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读