2013-06-13 191 views
28

我正在使用grunt连接我的Angular应用程序的.js文件。AngularJS:文件连接中断模块声明顺序

我刚刚完成并整理了代码库,以遵循here讨论的约定,特别是将我的代码分组为代表功能的小模块。

但是,我发现串联的顺序似乎破坏了应用程序,如果模块在声明之前被使用。

如:

|-- src/ 
| |-- app/ 
| | |-- userProfile/ 
| | | | userProfile.js 
| | | |-- deposits/ 
| | | | |-- depositFormCtrl.js 

其中:

// userProfile.js 
var userProfile = angular.module('userProfile',[]) 

// depositFormCtrl.js 
angular.module('userProfile') 
    .controller('DepositFormCtrl', function($scope) {...}); 

当咕噜进行级联,depositFormCtrl.jsuserProfile.js出现之前。这将导致应用程序引发错误,抱怨:

Uncaught Error: No module: userProfile

我看到很多谈论使用RequireJS的可能性/ AMD管理模块的加载顺序。但是,经常说这是过度/不需要的,as Angular handles this for you

E.g:对角队mentioned的布赖恩·福特:

My personal take is that RequireJS does too much; the only feature that AngularJS's DI system is really missing is the async loading.

他还指出elsewhere,他不与角推荐RequireJS。

我也见过提到使用angular-loader.js,如seed project所示。然而,据我所知,装载程序旨在解决加载模块失序的问题,而不是在使用前引用它们。

将angular-loader.js添加到我的项目中并未解决问题。

是否有我应该使用的声明来防止我遇到的错误?

什么是正确的方式来声明模块&控制器,以便命令文件连接不会影响运行时的代码?

+0

这就是为什么我建议使用RequireJS有棱有角。 RequireJS让您可以轻松定义所有脚本的加载顺序,而且,在部署到生产环境时,您可以使用r.js(RequireJS优化器),它可以跟随加载顺序定义文件,并按照以下顺序准确连接文件你指示它这样做。这就是我在我的项目中所做的,它完美的工作。 – Stewie

+1

我不知道这是否能解决您的问题(它是我的)。但我不得不加载app.js第一(该文件与'VAR app'声明,然后我可以通配符文件的其余部分与'咕噜-的contrib-concat' – chovy

回答

16

一种技术有时我用的是把声明的连结文件的开始。我这样做是通过将它们放入一个专用文件中来完成的,该文件将是第一个由连接实用程序提取的文件。

//app/_declarations.js 
angular.module('userProfile',[]); 

//app/userProfile/userProfile.js 
angular.module('userProfile') 
    .config(['$routeProvider', function ($router) {...}); 

//app/userProfile/deposits/depositFormCtrl.js 
angular.module('userProfile') 
    .controller('DepositFormCtrl', function($scope) {...}); 

可能不适合所有场景,但易于设置和理解。

+0

这是我结束了去的道路。这是牛逼不花哨,但很有效。 –

+0

如果使用呦,它做同样的事情,有一个顶级app.js定义模块,它总是被优先处理。 – grettke

+0

请给埃德信用他的回答。 – grettke

1

如果您将模块拆分为多个js文件,并且您不想按照哪个顺序手动管理您的构建应连接文件,那么您将需要RequireJS。

就个人而言,我会尽量避免在几个文件分割模块有以下几个原因:

  • 它可以是很难找到的所有控制器/服务/等等。从单个模块
  • 如果模块变得太大,那么这可能意味着你应该拆分成几个模块
  • 这很麻烦,必须手动声明模块依赖关系列表和每个模块的注入依赖列表。再加上RequireJS需要的js依赖文件列表,你会花大部分时间来宣布无聊的东西,而不是解决业务问题

但是,如果你保留1模块/ 1文件规则,你会请参阅您的index.html非常快速地增长。就我个人而言,我不认为这是一个大问题。

2

我碰到了同样的问题。我将我的GruntFile.js中的连接步骤拆分为两个任务,所以本质上我的app.js(我的Angular应用程序被定义的地方)被'前置'到中间连接文件(_app.js),并且结果与中间文件的名称相同,得到的成最终 '_app.js'

app.js

var TestApp = angular.module('TestApp', [...]); 

子任务在我GruntFile.js

.... 
// Concatenate all Angular application JS files into _app.js. Note the use 
// of wildcards to walk the App folder subfolders to pick up all JS files. 
     jsCore: { 
      src: [     
       '<%= meta.appPath%>/**/*.js', 

       // Do not include app.js, since it needs to be prepended to the final concat file 
       '!<%= meta.appPath/app.js', 

       // Do not include config.js, since it will need to be tokenized by RM 
       '!<%= meta.appPath%>/config.js' 
      ], 
      dest: '<%= meta.resPath %>/_app.js' 
     }, 

     // Prepend app.js to the beginning of _app.js, and save result as _app.js. 
     // This keeps Angular happy ... 
     jsApp: { 
      src: [ 
       '<%= meta.appPath%>/app.js', 
       '<%= meta.resPath%>/_app.js' 
      ], 
      dest: '<%= meta.resPath %>/_app.js' 
     } 
... 

所得的我的concat部_app.js文件在开始处具有app.js的来源,即Te的声明斯塔普。

1

使用一饮而尽,然后用一口棱角排序

return gulp.src('./build/src/app/**/*.js') 
     .pipe(sort()) 
     .pipe(plug.concat('concat.js')) 
     .pipe(gulp.dest('./output/'));