2013-06-13 2 views
28

ich grunzen bin mit meiner .js Dateien für meine Angular App verketten.AngularJS: Datei Verkettung Umbrüche Moduldeklaration um

Ich bin gerade durchgegangen und habe die Codebasis aufgeräumt, um den Konventionen zu folgen, die here besprochen werden, spezifisch, meinen Code in kleine Module gruppierend, die Eigenschaften darstellen.

aber ich finde, dass die Reihenfolge der Verkettung erscheint die App zu brechen, wenn ein Modul verbraucht wird, bevor sie deklariert wird.

zB:

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

Wo:

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

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

Wenn grunzen die Verkettung führt, erscheint depositFormCtrl.js vor userProfile.js. Dies bewirkt, dass die App einen Fehler werfen, beschweren:

Uncaught Error: No module: userProfile

Ich sehe eine Menge Gerede über die Möglichkeiten der Verwendung RequireJS/AMD die Ladereihenfolge der Module verwalten. Oft wird jedoch angegeben, dass dies zu viel verlangt/nicht erforderlich ist, as Angular handles this for you.

Z. B: Brian Ford des Angular Team 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.

Er ist auch elsewhere erklärt, dass er nicht RequireJS mit kantigem nicht empfiehlt.

Ich habe auch erwähnt, dass mit angular-loader.js gemacht, wie auf der seed project gezeigt. Wie ich jedoch verstehe (es gibt wenig offizielle Dokumentation), zielt der Loader darauf ab, das Problem zu lösen, Module nicht in der richtigen Reihenfolge zu laden, anstatt sie vor der Verwendung zu referenzieren.

Hinzufügen Winkel loader.js zu meinem Projekt nicht das Problem behoben wurde.

Gibt es eine Deklaration, die ich verwenden sollte, die die Fehler verhindert, die ich habe?

Was ist die korrekte Deklaration von Modulen & Controller, so dass die Reihenfolge der Dateien verkettet ist, hat keinen Einfluss auf den Code zur Laufzeit?

+0

Das ist genau, warum ich mit RequireJS mit kantigem empfehlen. Mit RequireJS können Sie ganz einfach die Ladereihenfolge aller Ihrer Skripte definieren, und bei der Bereitstellung in der Produktion verwenden Sie r.js (den RequireJS-Optimierer), der Ihrer Ladeauftragsdefinitionsdatei folgen und die Dateien genau in der Reihenfolge verketten kann Sie weisen es an zu tun. Das mache ich bei meinen Projekten und es funktioniert perfekt. – Stewie

+1

Ich weiß nicht, ob das dein Problem behebt (es hat meins). Aber ich musste zuerst app.js laden (die Datei mit der 'var app' wurde deklariert, dann konnte ich den Rest der Dateien mit' grunt-contrib-concat' versehen. – chovy

Antwort

16

Eine Technik, die ich manchmal verwende, ist, Deklarationen an den Anfang der verketteten Datei zu setzen. Ich tue das, indem ich sie in eine dedizierte Datei lege, die die erste ist, die vom Verkettungsprogramm aufgenommen wird.

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

Kann nicht für alle Szenarien geeignet sein, ist aber einfach einzurichten und zu verstehen.

+0

Dies ist der Pfad, mit dem ich am Ende war. –

+0

Wenn Sie Yo verwenden, tut es das gleiche, es gibt eine Top-Level app.js, die das Modul definiert und es wird immer zuerst verarbeitet. – grettke

+0

Bitte geben Sie Ed Kredit für seine Antwort. – grettke

1

Wenn Sie ein Modul in mehrere JS-Dateien aufteilen und nicht manuell in der Reihenfolge, in der Ihr Build Dateien verketten soll, verwalten möchten, benötigen Sie RequireJS.

Ich persönlich versuchen, ein Modul in mehreren Dateien aus mehreren Gründen zu vermeiden Aufspaltung:

  • Es kann schwierig sein, alle Controller/Dienstleistungen zu finden/etc .. aus einem einzigen Modul
  • Wenn das Modul wird zu groß, dann bedeutet es wahrscheinlich, dass Sie in mehrere Module aufgeteilt werden sollten
  • Es ist umständlich genug, manuell eine Liste von Modulabhängigkeiten und eine Liste von injizierten Abhängigkeiten für jedes Modul zu deklarieren.Hinzu kommt, dass eine Liste von js Abhängigkeitsdateien RequireJS benötigt, und Sie werden die meiste Zeit erklären langweilige verbringen, anstatt die Lösung von Geschäftsproblemen

Wenn Sie jedoch die 1 Modul/1 Datei Regel halten, werden Sie sehen Sie Ihre index.html wächst sehr schnell. Persönlich halte ich das nicht für ein großes Problem.

2

Ich stieß auf das gleiche Problem. Ich habe den Verkettungsschritt in meiner GruntFile.js auf zwei Aufgaben aufgeteilt, also wird im Wesentlichen meine app.js, in der meine Angular-Anwendung definiert ist, der dazwischenliegenden verketteten Datei (_app.js) "vorangestellt", und das Ergebnis wird mit der gleichen Namen der Zwischendatei, die sich in eine endgültige '_app.js'

app.js

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

Teilaufgaben in meinem concat Abschnitt meiner 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' 
     } 
... 

Das resultierende _app.js Datei hat die Quelle von app.js am Anfang dh die Deklaration von Te stApp.

1

Verwendung schluck und verwenden Sie dann schluck-Winkel Art

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