28

我正在使用 grunt.js为我的 Angular 应用程序连接我的文件。

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

但是,我发现如果在声明模块之前使用了模块,则连接顺序似乎会破坏应用程序。

例如:

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

在哪里:

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

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

当 grunt 执行连接时,depositFormCtrl.js出现在userProfile.js. 这会导致应用程序抛出错误,抱怨:

未捕获的错误:没有模块:userProfile

我看到很多关于使用 RequireJS / AMD 管理模块加载顺序的可能性的讨论。然而,经常有人说这是矫枉过正/不是必需的,因为 Angular 会为你处理这个问题

例如:Angular 团队的 Brian Ford提到

我个人认为 RequireJS 做的太多了。AngularJS 的 DI 系统真正缺少的唯一功能是异步加载。

他还在其他地方表示他不推荐使用 Angular 的 RequireJS。

我还看到提到使用angular-loader.js,如种子项目所示。但是,据我了解,(官方文档很少)加载程序旨在解决加载模块乱序的问题,而不是在使用之前对其进行引用。

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

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

声明模块和控制器的正确方法是什么,以便连接订单文件不会影响运行时的代码?

4

4 回答 4

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) {...});

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

于 2013-06-13T11:41:13.760 回答
2

我遇到了同样的问题。我将 GruntFile.js 中的连接步骤拆分为两个任务,因此本质上我的 app.js(定义了我的 Angular 应用程序)被“添加”到中间连接文件 (_app.js) 中,结果与中间文件的同名,产生最终的“_app.js”

应用程序.js

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

我的 GruntFile.js 的 concat 部分中的子任务

....
// 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'
        }
...

生成的 _app.js 文件开头有 app.js 的来源,即 TestApp 的声明。

于 2014-11-03T20:27:40.710 回答
1

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

就个人而言,出于以下几个原因,我尽量避免将模块拆分为多个文件:

  • 很难从单个模块中找到所有控制器/服务/等
  • 如果模块变得太大,那么这可能意味着你应该分成几个模块
  • 必须手动声明模块依赖项列表和每个模块的注入依赖项列表,这已经够麻烦了。添加RequireJS所需的js依赖文件列表,您将花费大部分时间声明无聊的东西而不是解决业务问题

但是,如果您保持 1 个模块/1 个文件的规则,您会看到您的 index.html 增长得非常快。就个人而言,我不认为这是一个大问题。

于 2013-06-13T09:10:29.720 回答
1

使用 gulp 然后使用 gulp-angular-sort

return gulp.src('./build/src/app/**/*.js')
        .pipe(sort())
        .pipe(plug.concat('concat.js'))
        .pipe(gulp.dest('./output/'));
于 2016-08-04T15:30:46.157 回答