2012-10-16 9 views
14

To jest mój pierwszy raz, kiedy używam Grunta i chciałbym, żeby to wszystko łączyło wszystkie moje moduły js, z których każdy jest zawarty w funkcji natychmiastowej realizacji, zawierające deklarację "użyj ścisłego" i umieść je w jednym pliku, zawiniętym tylko w jedną funkcję natychmiastowego wykonywania, z tylko jedną deklaracją "użyj ścisłego".Próbuję użyć Grunta i potrzebuję prostego sposobu na połączenie moich modułów.

Jak to zwykle robi się?

Pomyślałem, że to będzie typowy przypadek użycia? Może robię coś niewłaściwego? Czy powinienem używać jednego z formatów ładowania modułów (tj. Commonjs, amd) Wszystkie te pliki będą zawsze ładowane razem w przeglądarce, więc właściwie nie miałbym nic przeciwko usunięciu wszystkich natychmiast wykonywanych funkcji, jeśli tak normalnie ludzie robią to. Ważną częścią jest to, że wynik końcowy jest w pewien sposób zawijany, przechodzi szarpie i testy jednostkowe i zawiera deklarację "ścisłe użycie".

(Powinienem wyjaśnić, mam to działa, linting, testowanie jednostkowe, konkatenacja i minifying, to po prostu wydaje się, że robię coś złego, gdy widzę grupę niepotrzebnych natychmiast wykonujących funkcje w końcowej połączonej plik.)

Odpowiedz

22

Zwykle robię to jak jQuery team does it. Utworzyć intro.js i outro.js i umieścić wszystko w dniach:

intro.js

;(function(window, undefined){ 
    'use strict'; 

outro.js

}(window)); 

grunt.js:

concat: { 
    dist: { 
    src: [ 
     'js/src/intro.js', 
     ... 
     'js/src/outro.js' 
    ], 
    dest: 'js/out/app.js' 
    } 
} 
+0

cholera, ja nawet nie spojrzał w ich github repo, aby zobaczyć, jak oni to zrobili, ale zupełnie nie zrozumiałem, że dzięki! – uglymunky

+1

Właściwie używam chrząknięcia, aby to zrobić z moim statycznym html podczas programowania. I zacząłem robić to samo z js, ale zamiast intro/outro używam head and footer. Ponieważ nie muszę dynamicznie aktualizować tytułów dokumentów podczas programowania, działa to świetnie. – jonschlinkert

2

Po prostu chcesz dodać do @elclanrs odpowiedź, że jeśli chcesz mieć możliwość przechowywania modułów w oddzielnych plikach w celu łatwiejszego debugowania podczas programowania, oczywiście musisz je również opakować za pomocą intro.js i outro.js. Korzystanie z wbudowanego concat zadania trzeba by napisać coś takiego:

concat: { 
    events_debug: { // wrap the 'events' module in IIFE 
    src: [ 
     'js/src/intro.js', 
     'js/src/events.js', 
     'js/src/outro.js' 
    ], 
    dest: 'js/out/events.js' 
    }, 
    callbacks_debug: { // wrap the 'callbacks' module in IIFE 
    src: [ 
     'js/src/intro.js', 
     'js/src/callbacks.js', 
     'js/src/outro.js' 
    ], 
    dest: 'js/out/callbacks.js' 
    } 

    // zzZZZ... 
} 

co jest bardzo uciążliwe i self-powtarzania. Być może zechcesz utworzyć niestandardowe zadanie do plików masowego zawijania, np.

wrap: { 
    html: { 
     intro: 'partials/intro.js', 
     outro: 'partials/outro.js', 
     src: 'js/*.js', 
     dest: 'out' // output directory 
    } 
} 

Nie było mowy o tym niedawno, zobacz ten wątek:

Using grunt concat, how would I automate the concatenation of the same file to many other files?

+1

Dzięki @Dmitry, myślę, że powoli rozumiem, jak to działa, nie jest to bardzo proste. Zastanawiam się, czy sensownym rozwiązaniem jest napisanie każdego modułu owiniętego w życie, a następnie zadanie pomruczenia, które rozbiera opakowanie. Tak jak może usuwa wszystko przed '// <- intro' i wszystko po' // outro -> '...? – uglymunky

+0

... Domyślam się, że "wrap" zamiast "unwrap" przylega lepiej do "DRY" – uglymunky

+0

To zależy od ciebie :) Oczywiście łączenie jest łatwiejsze, bezpieczniejsze i szybsze niż zdejmowanie wzoru. Ale z drugiej strony, nie jestem pewien, czy podoba mi się to, że moje pliki źródłowe są zależne od narzędzia do budowania (np. Twoje moduły nie są już przenośne, ponieważ nie działają bez zapakowania w IIFE. musisz ręcznie usunąć IIFE z dowolnych zewnętrznych modułów, które dodasz do swojego projektu). Tak dobre rozważania ... –

34

Od pull request 10, grunt-contrib-concat ma teraz opcję footer. Zamiast pliku wejściowego i wyjściowego użyłbym banner i footer.

Gruntfile.js

concat: { 
    dist: { 
    src: ['src/my-lib.js'], 
    dest: 'dist/<%= pkg.name %>.js', 
    options: { 
     banner: ";(function(window, undefined){ \n 'use strict';", 
     footer: "}(window));" 
    } 
    } 
} 

moim zdaniem, jest to bardziej w utrzymaniu i pozwala na templating użyciu innych właściwości zdefiniowane w Gruntfile.

+0

Zgadzam się, jest to o wiele lepsze niż jakakolwiek inna opcja, a ponieważ jest to oficjalne wydanie Grunt, możesz być pewien, że wtyczka zostanie zachowana. – Rodrigo

1

Polecam użyć mojej wtyczki grunt-concat-deps, ponieważ automatycznie rozwiązuje ona moduły niezależne od architektury.

PLUS: Nie trzeba żadnej konfiguracji modułu wyraźny dla wtyczki, ponieważ opiera się na deklaratywnej i zdecentralizowanej definicji modułu w stylu YUIDoc.

Patrz tutaj dla dalszych informacji: https://github.com/leoselig/grunt-concat-deps

Powiązane problemy