我正在开发一个AngularJS应用程序.要在生产中发布代码,我正在使用这个Grunt配置/任务:
grunt.registerTask( 'compile', [
'sass:compile', 'copy:compile_assets', 'ngAnnotate', 'concat:compile_js', 'uglify', 'index:compile'
]);
Run Code Online (Sandbox Code Playgroud)
调试真的很难,对于那些已经遇到过这些问题并且可以指向某个方向的人来说,这是一个问题.
我的主要模块包括那些子模块:
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);
Run Code Online (Sandbox Code Playgroud)
我得到的错误如下:
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
Run Code Online (Sandbox Code Playgroud)
如果我删除网站模块,我得到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'
]);
Run Code Online (Sandbox Code Playgroud)
那么也许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'
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
更新2:
问题似乎与concat有关.
它需要每个JS文件并将其一个接一个地添加到一个更大的文件中.我的所有模块都在最后.最后一个模块始终存在"已定义状态"的问题.所以这不仅仅是模块的顺序相互依赖,这是一个很好的例子......
更新3: 我在一个要点中放置了我的代码(我已经排除了每个控制器代码和函数,只是脚手架).这是我编译过程之后的结果,没有弄清楚它.
Dan*_*nte 21
问题:
您有多个文件包含config配置模块的功能,如下所示:
angular
.module('controlcenter.websites', [])
.config(config);
function config() {
// ...
}
Run Code Online (Sandbox Code Playgroud)
问题是,在连接所有文件之后,最终会得到一个带有多个声明的大文件config.由于JavaScript的变量提升,所有声明都被移到顶部,只评估它们中的最后一个,这个是:
function config($stateProvider) {
$stateProvider.state( 'websites', {
url: '/websites',
views: {
"main": {
controller: 'WebsitesController',
templateUrl: 'websites/overview/websites.tpl.html'
}
},
data : {requiresLogin : true }
});
}
Run Code Online (Sandbox Code Playgroud)
因此,每次.config(config)使用模块时,都要告诉Angular使用该特定配置函数配置模块,这意味着它会多次执行并尝试多次定义状态websites.
解:
用闭包包装每个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);
Run Code Online (Sandbox Code Playgroud)
编辑:
我强烈建议你将文件包装成闭包.但是,如果您仍然不想这样做,可以根据各自的模块命名您的功能.这样你的配置功能controlcenter.website.details就会变成controlcenterWebsiteDetailsConfig.另一个选择是在构建阶段使用grunt-wrap包装代码.
window.angular和闭包:当我要对它进行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);
Run Code Online (Sandbox Code Playgroud)
可以很容易地对此进行修改(注意每个引用都angular被替换为a):
!function(a){a.module("app",["controllers"]),a.module("controllers",[])}(window.angular);
Run Code Online (Sandbox Code Playgroud)
另一方面,一个未打包的代码片段如下:
angular.module('app', ['controllers']);
angular.module('controllers', []);
Run Code Online (Sandbox Code Playgroud)
会成为:
angular.module("app",["controllers"]),angular.module("controllers",[]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9575 次 |
| 最近记录: |