2013-06-13 10 views
28

Używam pomruków do łączenia moich plików .js dla mojej aplikacji Angular.AngularJS: Łączenie plików łamie kolejność deklaracji modułu

Właśnie przeszedłem i uporządkowałem bazę kodów, aby przestrzegać konwencji omawianych pod here, w szczególności, zgrupowanie mojego kodu w małe moduły, które reprezentują funkcje.

Jednak stwierdzam, że kolejność konkatenacji wydaje się przerwać aplikację, jeśli moduł zostanie zużyty, zanim zostanie zadeklarowany.

np

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

gdzie:

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

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

gdy grunt wykonuje konkatenacji depositFormCtrl.js pojawia się przed userProfile.js. To powoduje, że aplikację wyrzucić błąd, twierdząc:

Uncaught Error: No module: userProfile

widzę dużo mówi się o możliwości wykorzystania RequireJS/AMD zarządzać kolejność ładowania modułów. Jednak często mówi się, że jest to przesadne/niewymagane, as Angular handles this for you.

Np: Brian Ford kątowego zespołu 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.

On również stwierdził elsewhere że nie zaleca RequireJS z kątowy.

Zauważyłem również, że wspomniano o zastosowaniu angular-loader.js, jak pokazano na seed project. Jednak, jak rozumiem, (nie ma oficjalnej dokumentacji), ładowarka ma na celu rozwiązanie problemu ładowania modułów w kolejności, a nie ich odniesienie przed użyciem.

Dodanie pliku angle-loader.js do mojego projektu nie rozwiązało problemu.

Czy istnieje deklaracja, której powinienem użyć, aby zapobiec błędom, które mam?

Jaki jest prawidłowy sposób deklarowania modułów Sterowniki &, aby pliki zamówień były łączone, nie ma wpływu na kod w czasie wykonywania?

+0

To właśnie dlatego zalecamy używania RequireJS z kątowy. RequireJS pozwala ci dość łatwo zdefiniować kolejność ładunków wszystkich twoich skryptów, a następnie, podczas wdrażania do produkcji, używasz r.js (optymalizator RequireJS), który może śledzić twój plik definicji porządku ładowania i łączyć pliki dokładnie w takiej kolejności, w jakiej ty to poinstruuj. Właśnie to robię w moich projektach i działa idealnie. – Stewie

+1

Nie wiem, czy to naprawi twój problem (zrobił to mój). Ale najpierw musiałem wczytać plik app.js (zadeklarowałem plik z aplikacją "var app", a potem mogłem wprowadzić pozostałe elementy w pliku z "grunt-contrib-concat" – chovy

Odpowiedz

16

Jedną z technik, której czasami używam, jest umieszczanie deklaracji na początku połączonego pliku. Robię to poprzez umieszczenie ich w dedykowanym pliku, który będzie pierwszym, który zostanie pobrany przez narzędzie do konkatenacji.

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

Może nie pasować do wszystkich scenariuszy, ale jest prosty w konfiguracji i zrozumieniu.

+0

To jest ścieżka, którą zakończyłem. Nie jest to wymyślne, ale działa. –

+0

Jeśli używasz Yo, robi to samo, jest app.js najwyższego poziomu, który definiuje moduł i zawsze jest przetwarzany jako pierwszy – grettke

+0

Podaj wartość kredytu Ed dla swojej odpowiedzi – grettke

1

Jeśli podzielisz moduł na wiele plików js i nie chcesz zarządzać ręcznie, w jakiej kolejności kompilacja powinna łączyć pliki, będziesz potrzebować RequireJS.

Osobiście staram się unikać dzielenia modułu w kilku plików z kilku powodów:

  • To może być trudne, aby znaleźć wszystkie kontrolery/usługi/itp .. z jednego modułu
  • Jeśli moduł staje się zbyt duży, to prawdopodobnie oznacza, że ​​powinieneś podzielić się na kilka modułów.
  • Jest to na tyle kłopotliwe, że musisz ręcznie zadeklarować listę zależności modułów i listę wstrzykniętych zależności dla każdego modułu.Dodaj do tego listę plików zależności js wymaganych przez RequireJS, a będziesz spędzał większość czasu na zgłaszaniu nudnych rzeczy zamiast rozwiązywania problemów biznesowych

Jeśli jednak zachowasz regułę 1 modułu/1, będziesz zobacz, jak bardzo rośnie index.html. Osobiście nie uważam tego za duży problem.

2

Wpadłem na ten sam problem. Rozdzielam etap konkatenacji w moim pliku GruntFile.js na dwa zadania, więc zasadniczo moja aplikacja app.js, w której zdefiniowano moją aplikację Angular, jest "dodawana" do pośredniego pliku konkatenowanego (_app.js), a wynik jest zapisywany z Ta sama nazwa pliku pośrednim, prowadzące do ostatecznego '_app.js'

app.js

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

zadania podrzędne w mojej sekcji concat moich 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' 
     } 
... 

wypadkowej Plik _app.js ma źródło app.js na początku, tj. deklarację Te stApp.

1

użycie łyk, a następnie użyć łyk-kątowa-sort

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