Próbuję użyć Grunta jako narzędzia do kompilacji mojej aplikacji internetowej.
Chcę mieć co najmniej dwie konfiguracje:
I. Konfiguracja programistyczna - ładuj skrypty z oddzielnych plików, bez konkatenacji,
więc mój index.html wyglądałby mniej więcej tak:
<!DOCTYPE html>
<html>
<head>
<script src="js/module1.js" />
<script src="js/module2.js" />
<script src="js/module3.js" />
...
</head>
<body></body>
</html>
II. Konfiguracja produkcji - załaduj moje skrypty zminimalizowane i połączone w jednym pliku,
odpowiednio z index.html:
<!DOCTYPE html>
<html>
<head>
<script src="js/MyApp-all.min.js" />
</head>
<body></body>
</html>
Pytanie brzmi: w jaki sposób mogę zmusić chrząka, aby te index.html zależały od konfiguracji podczas uruchamiania grunt dev
lub grunt prod
?
A może kopie w złym kierunku i łatwiej byłoby zawsze wygenerować, MyApp-all.min.js
ale umieścić w nim wszystkie moje skrypty (połączone) lub skrypt ładujący, który asynchronicznie ładuje te skrypty z osobnych plików?
Jak to robicie chłopaki?
javascript
build
build-automation
gruntjs
Dmitrij Paszkiewicz
źródło
źródło
Odpowiedzi:
Niedawno odkryłem te
v0.4.0
zadania kompatybilne z Grunt :pomruk wstępny
grunt-env
Poniżej znajdują się moje fragmenty
Gruntfile.js
.Konfiguracja ENV:
Proces wstępny:
Zadania:
I w
/src/tmpl/index.html
pliku szablonu (na przykład):Jestem pewien, że moja konfiguracja różni się od większości ludzi, a przydatność powyższego zależy od twojej sytuacji. Dla mnie, mimo że jest to niesamowity kawałek kodu, Yeoman pomruk-usemin jest bardziej niezawodny niż osobiście potrzebuję.
UWAGA: I właśnie odkrył wyżej wymienione zadania dzisiaj, więc może brakować funkcji i / lub mój proces może ulec zmianie w dół drogi. Póki co, uwielbiam prostotę i funkcje, które mają do zaoferowania funkcje pre-procesowe i en-gruntowe . :)
Aktualizacja z stycznia 2014 r .:
Motywowany głosowaniem w dół ...
Kiedy opublikowałem tę odpowiedź, nie było wielu opcji dla Grunta,
0.4.x
które oferowały rozwiązanie, które działało na moje potrzeby. Teraz, miesiące później, zgaduję, że jest więcej opcji, które mogłyby być lepsze niż to, co tutaj zamieściłem. Chociaż nadal osobiście używam i lubię korzystać z tej techniki w moich kompilacjach , proszę przyszłych czytelników o przeczytanie innych udzielonych odpowiedzi i zbadanie wszystkich opcji. Jeśli znajdziesz lepsze rozwiązanie, opublikuj swoją odpowiedź tutaj.Aktualizacja z lutego 2014 r .:
Nie jestem pewien, czy przyniesie to jakąkolwiek pomoc, ale utworzyłem to repozytorium demonstracyjne na GitHub, które pokazuje pełną (i bardziej złożoną konfigurację) przy użyciu technik opisanych powyżej.
źródło
path : '/<%= pkg.name %>/dist/<%= pkg.version %>/<%= now %>/<%= ver %>'
zmienną, która łączy wszystkie zmienne (to moja ścieżka kompilacji). Na moim szablonu będę mieć:<script src="http://cdn.foo.com<!-- @echo path -->/js/bulldog.min.js"></script>
. W każdym razie cieszę się, że mogłem zaoszczędzić trochę czasu! : Ddata
obiekt dla dev / prod.Wymyśliłem własne rozwiązanie. Jeszcze nie dopracowane, ale myślę, że pójdę w tym kierunku.
W skrócie, używam grunt.template.process () do generowania mojego
index.html
z szablonu, który analizuje bieżącą konfigurację i tworzy albo listę moich oryginalnych plików źródłowych, albo łącza do pojedynczego pliku ze zminimalizowanym kodem. Poniższy przykład dotyczy plików js, ale to samo podejście można rozszerzyć na css i inne możliwe pliki tekstowe.grunt.js
:index.js (the index task)
:Wreszcie,
index.tmpl
z logiką generacji wypaloną:UPD. Okazało się, że Yeoman , oparty na chrząstce, ma wbudowane zadanie usemin, które integruje się z systemem kompilacji Yeoman. Generuje wersję produkcyjną pliku index.html na podstawie informacji w wersji rozwojowej pliku index.html, a także innych ustawień środowiska. Trochę wyrafinowany, ale interesujący.
źródło
grunt.template.process()
(którego tu używasz), który uczyniłby to jeszcze łatwiejszym. Możesz zrobić to samo, używając szablonu-gruntu , po prostu przekazując innydata
obiekt dla dev / prod.Nie podoba mi się tutaj rozwiązania (w tym te, które wcześniej podałem ) i oto dlaczego:
Zrozumiałem, jak rozwiązać oba te problemy. Skonfigurowałem moje zadanie karczowania, aby za każdym razem, gdy plik był dodawany lub usuwany, tagi skryptów były automatycznie generowane, aby to odzwierciedlić. W ten sposób nie musisz modyfikować pliku html ani chrząkać podczas dodawania / usuwania / zmiany nazw plików JS.
Podsumowując, jak to działa, mam szablon HTML ze zmienną dla znaczników skryptu. Korzystam z https://github.com/alanshaw/grunt-include-replace do wypełnienia tej zmiennej. W trybie deweloperskim ta zmienna pochodzi ze wzoru globowania wszystkich moich plików JS. Zadanie oglądania ponownie oblicza tę wartość, gdy plik JS jest dodawany lub usuwany.
Teraz, aby uzyskać różne wyniki w trybie deweloperskim lub produkcyjnym, wystarczy wypełnić tę zmienną inną wartością. Oto kod:
jsSrcFileArray
to Twój typowy wzorzec globowania plików.jsScriptTags
pobierajsSrcFileArray
i łączy je razem zscript
tagami po obu stronach.destPath
to prefiks, który chcę w każdym pliku.A oto jak wygląda HTML:
Teraz, jak widać w konfiguracji, generuję wartość tej zmiennej jako
script
tag zakodowany na stałe, gdy jest ona uruchomiona wprod
trybie. W trybie deweloperskim zmienna ta rozwija się do wartości takiej jak ta:Daj mi znać, jeśli masz jakieś pytania.
PS: To szalona ilość kodu do czegoś, co chciałbym zrobić w każdej aplikacji JS po stronie klienta. Mam nadzieję, że ktoś może to zmienić we wtyczkę wielokrotnego użytku. Może kiedyś to zrobię.
źródło
I've set up my grunt task so that every time a file is added or deleted, the script tags automatically get generated to reflect that
Jak to zrobiłeś?<script>
tagów HTML ?destPath
zjsScriptTags
i zamieniłemgrunt.file.expandMapping
zgrunt.file.expand
jak pliki chciałem były już w odpowiednich miejscach. To bardzo uprościło sprawy. Dziękuję @DanielKaplan, zaoszczędziłeś mi ogromnie dużo czasu :)Od dłuższego czasu zadaję sobie to samo pytanie i myślę, że ta wtyczka może być skonfigurowana do robienia tego, co chcesz: https://npmjs.org/package/grunt-targethtml . Implementuje warunkowe tagi HTML, które zależą od celu chrząknięcia.
źródło
Szukałem prostszego, prostszego rozwiązania, więc połączyłem odpowiedź z tego pytania:
Jak umieścić, jeśli inaczej blok w gruntfile.js
i wymyślił następujące proste kroki:
Użyj poniższej logiki w bloku concat / copy swojego pliku Gruntfile.js dla pliku index.html:
uruchom „grunt --Release”, aby wybrać plik index-production.html i pozostaw flagę, aby mieć wersję programistyczną.
Brak nowych wtyczek do dodania lub skonfigurowania oraz brak nowych zadań chrząknięcia.
źródło
To chrząknięcie o nazwie scriptlinker wygląda na łatwy sposób dodawania skryptów w trybie programistycznym. Prawdopodobnie możesz najpierw uruchomić zadanie konkat, a następnie skierować je do pliku konkatenowanego w trybie prod.
źródło
<!--SINON COMPONENT SCRIPTS-->
i<!--SPEC SCRIPTS-->
. A oto zadanie Grunt, które to robi (faktycznie działające, w przeciwieństwie do tego, co jest w dokumentach). Mam nadzieję, że to pomaga;)grunt-dom-munger czyta HTML i manipuluje nim za pomocą selektorów CSS. Dawny. odczytaj tagi z html. Usuń węzły, dodaj węzły i nie tylko.
Możesz użyć grunt-dom-munger, aby odczytać wszystkie pliki JS, które są połączone przez twój index.html, uglifikować je, a następnie użyć ponownie grunt-dom-munger, aby zmodyfikować index.html, aby połączyć tylko zminimalizowany JS
źródło
Znalazłem wtyczkę chrząka o nazwie chrobot-dev-prod-switch. Jedyne, co robi, to komentowanie pewnych bloków, których szuka, na podstawie opcji --env, którą przekazujesz do chrząknięcia (chociaż ogranicza cię to do tworzenia, dźgania i testowania).
Po ustawieniu go jako wyjaśnia tutaj , można uruchomić na przykład:
grunt serve --env=dev
, a wszystko to komentuje bloki, które są owiniętei odkomentuje bloki, które są owinięte
Działa również na javascript, używam go do ustawiania właściwego adresu IP do połączenia z moim interfejsem API. Bloki po prostu zmieniają się na
W twoim przypadku byłoby to tak proste:
źródło
chrząknięcie to fantastyczny skrypt, który świetnie się tu sprawdzi. Używam go w moim skrypcie automatycznego budowania JQM.
https://github.com/imaginethepoet/autojqmphonegap
Spójrz na mój plik grunt.coffee:
Spogląda na wszystkie pliki w pliku base.html i zasysa je, aby utworzyć plik index.html. Działa fantastycznie w aplikacjach wielostronicowych (phonegap). Pozwala to na łatwiejszy rozwój, ponieważ wszyscy deweloperzy nie pracują na jednej długiej, jednostronicowej aplikacji (zapobiegając wielu kontrolom konfliktów). Zamiast tego możesz podzielić strony i pracować na mniejszych fragmentach kodu i skompilować do pełnej strony za pomocą polecenia watch.
Bake czyta szablon z base.html i wstrzykuje strony HTML komponentu do zegarka.
jQuery Mobile Demos
app.initialize ();
Możesz pójść o krok dalej i dodać zastrzyki na swoich stronach do wyskakujących okienek „menu”, „itp”, aby naprawdę podzielić strony na mniejsze, łatwe do zarządzania komponenty.
źródło
Użyj kombinacji przewodowej https://github.com/taptapship/wiredep i usemin https://github.com/yeoman/grunt-usemin , aby chrząknąć zajął się tymi zadaniami. Wiredep doda Twoje zależności jeden plik skryptu na raz, a usemin połączy je wszystkie w jeden plik do produkcji. Można to zrobić za pomocą kilku komentarzy HTML. Na przykład moje pakiety altanki są automatycznie dołączane i dodawane do html po uruchomieniu
bower install && grunt bowerInstall
:źródło
Ta odpowiedź nie dotyczy noobów!
Użyj szablonów Jade ... przekazywanie zmiennych do szablonu Jade to standardowy przypadek użycia torfowiska
Używam chrząknięcia (chrząknięcie-contrib-jade), ale nie musisz chrząkać. Wystarczy użyć standardowego modułu jade npm.
Jeśli używasz chrząknięcia, Twój plik chrząstek chciałby czegoś takiego ...
Możemy teraz łatwo uzyskać dostęp do danych przekazywanych przez chrząknięcie w szablonie Jade.
Podobnie jak podejście zastosowane przez Modernizra, ustawiam klasę CSS na znaczniku HTML zgodnie z wartością przekazywanej zmiennej i mogę użyć logiki JavaScript na podstawie tego, czy klasa CSS jest obecna, czy nie.
Jest to świetne, jeśli używasz Angulara, ponieważ możesz zrobić ng-if, aby uwzględnić elementy na stronie w zależności od tego, czy klasa jest obecna.
Na przykład mogę dołączyć skrypt, jeśli klasa jest obecna ...
(Na przykład mogę załączyć skrypt przeładowania na żywo w dev, ale nie w produkcji)
źródło
Zastanów się processhtml . Pozwala zdefiniować wiele „celów” dla kompilacji. Komentarze służą do warunkowego dołączania lub wykluczania materiałów z HTML:
staje się
Podobno nawet robi takie fajne rzeczy (zobacz README ):
źródło