Autor Zpráva
joe
Profil
Ahoj,

zajímalo by mě, jak řešite minifikaci (případně i obfuskaci) nějak globálně při deploymentu? V práci se chystá na nasazení Grunt, ale osobně mi to nepřijde moc ideální a musí to každý člověk spouštět sám, ikdyž na to budou předpřipravené skripty. Nelíbí se mi to, protože to neukáže chybu (nebo tedy jen možná nevím, jak zobrazování chyb nastavit) kde je přesně problém. Dál se mi moc nelíbí, že v šabloně budu mít vypsány neminifikované verze a v druhé části else budou už načítány minifikované soubory - povede to k chybám, že se prostě někam soubor zapomene připsat.

Neporadíte někdo nějaký lepší způsob, jak to vše zautomatizovat, mně by se líbilo, kdyby to vše proběhlo třeba před commitem do Git repozitáře a v případě chyby by ke commitnutí nedošlo. Ale pořád nevím jak řešit to vkládání těch souborů - prostě aby mi existoval jen jeden seznam souborů a ne dva.

Díky )
loyza
Profil
Aby existoval jen jeden seznam souborů je asi nereálné. Ať si to ujasníme. Ty si představuješ, že při commitu se tvoje javascripty a csska zminifikují a v repozitáři budou jen zminifikované verze? Jak v tom pak budeš dělat úpravy?
llook
Profil
Buildované soubory nepatří do repozitáře. Vývojáři pracují s nezbuildovanými soubory a build provádí až deploy server (stačí ta nejlevnější VPS cca za 100 Kč/měs) po pushnutí do deploy větve.

CSS není problém, máš jeden soubor s @import příkazy, který používáš jak pro vývoj, tak pro build. Trochu problém může být s JS, tam ty soubory píšeš na dvě místa (do šablony a do gruntfile). Řešením by mohlo být místo grunt-contrib-uglify používat grunt-contrib-requirejs, u toho snad není potřeba soubory vyjmenovávat, stačí zadat složku. Ale nevím, nějak hlouběji jsem se tím nezabýval.


loyza:
Ty si představuješ, že při commitu se tvoje javascripty a csska zminifikují a v repozitáři budou jen zminifikované verze? Jak v tom pak budeš dělat úpravy?
Ne, on si představuje, že v šabloně bude nějaký "if produkce/else vývoj", přičemž tu produkci mu bude generovat nějaký nástroj. To je správný způsob, až na to, že je blbost, aby si to pouštěl každý sám a commitoval výsledek. Pokud na projektu dělá víc lidí, tak to vede ke kolizím v těch buildovaných souborech a všichni to musí pořád dokola řešit.
joe
Profil
loyza:
Do repozitáře bych dával obě verze - normální a minifikované nějakým nástrojem.

llook:
Vývojáři pracují s nezbuildovanými soubory a build provádí až deploy server
Co myslíš tím deploy serverem a deploy větví?

CSS není problém, máš jeden soubor s @import příkazy, který používáš jak pro vývoj, tak pro build
A na vývojovém stroji, jak rozhodnu, že budu načítat neminifikované verze?

Ty to myslíš tak, že minifikované soubory budou mít na produkci stejný název souboru, jako při vývoji? (*)

Trochu problém může být s JS
A proč ne i s CSS? Nechci hromadu souborů CSS, chci třeba skupinku CSS - opět dva seznamy.

To je správný způsob, až na to, že je blbost, aby si to pouštěl každý sám a commitoval výsledek.
... Ano, tak nějak to je unás myšleno a také se mi to nelíbí. Ale má to i své výhody - minifikace JavaScriptu se nemusí podařit a mohlo by dojít na deploy serveru k chybě.


(*) Zároveň bych chtěl mít možnost načíst na produkčním webu neminifikované soubory pro rychlé ladění. Třeba přes parametr v URL (+ pak kontroly přístupu, apod.)
Alphard
Profil
joe:
Co myslíš tím deploy serverem a deploy větví?
Deploy větev, my jí máme pojmenovanou production, je větev, podle které se automaticky aktualizují soubory webu. Udělá se rebase z master na production, pushne se výsledek a web je aktulizován. Máme na to nastavené i mazání tempu apod., ručně jen aktualizuji změny v databázi.

Také mám nyní na stole vyřešení problému s css a js. Stavím na řešení volání jediného css a js souboru. Do toho jsou includovány jednotlivé soubory, věřím, že bych je dokázal minifikovat, i když to zatím nedělám. Nyní hledám nějaký elegantní způsob, jak automatizovat zvýšení verze u načítání scriptu, např. script.js?v=102, když dojde ke změně některého z includovaných souborů.
Kcko
Profil
Alphard:
proč ji potřebuješ zvyšovat?
Kvůli informaci o verzi nebo keši v prohlížeči?
Alphard
Profil
Kcko:
Kvůli cache.
Kcko
Profil
Alphard:
Tak na to stačí jednoduché soubor?zmena=<?= filemtime("soubor"); ?> ne?
joe
Profil
Alphard:
Pokud i llook myslel deploy větví tu, kterou ty popisuješ, tak tam právě může vzniknout problém při minifikaci. Tzn. z úkolu na pár minut se stane úkol na hodinu, že se bude řešit, proč to nefunguje, protože třeba jenom někdo někam zapomněl přidat středník. To se mi nelíbí.

Stavím na řešení volání jediného css a js souboru.
To mi nepřijde správné, protože když includuješ třeba 30 JS souborů a a třeba jen opravíš překlep, proč budeš nutit všechny, aby si stáhli celý balík souborů znovu? To je zbytečné.

Nyní hledám nějaký elegantní způsob, jak automatizovat zvýšení verze u načítání scriptu, např. script.js?v=102
Můžeš to udělat takto:

script.js?... a místo ... doplníš datum změny souboru.
Alphard
Profil
Děkuji za návrhy, podobný princip byla první byla první věc, co mě napadla; nyní to tak mám, pouze tam přes vlastní funkci procházím seznam souborů. Byl bych ale radši, kdyby se to během deploye upravilo fixně, nyní si hraji s náhradou něčeho jako @JS_VERSION@. Ve volných chvílích to postupně vylepšuji, zrovna tohle mě teď moc netíží, jen jsem to zmínil, že joe založil tohle vlákno.

Pokud jde o opravu překlepů, nejsou zas tak časté a ten výsledný soubor není zas tak velký (ve srovnání s pár obrázky), takže to neřeším.

Jde-li o chyby při minifikaci, nemám zkušenosti, ale co třeba hned při commitu zkusit provést (a výsledek zahodit)? Když to projde, je to ok a půjde to i později.
llook
Profil
joe:
Co myslíš tím deploy serverem a deploy větví?
Deploy server je prostě VPS, která někde pořád běží a ve chvíli, kdy někdo provede push do deploy větve v centrálním repozitáři, tak spustí deployment.

Na té VPS máme nainstalovaný Gitlab CI, který spustí nějaký náš skript. Výstup toho skriptu je dostupný přes webové rozhranní, spolu s informací o tom, jestli neskončil chybou (podle exit kódu). Ten skript projede testy, vytvoří buildy JS a CSS a když všechno dobře dopadne, tak aktualizuje produkční server - přenese změněné soubory z repozitáře (podle diffu mezi aktuálním a naposledy deployovaným commitem), přenese nově zbuildované soubory a smaže temp. Ještě to nemáme úplně vychytané, ale v principu to tak funguje. Pokud něco selže, ať už testy, nebo grunt, tak proces nedoběhne, na produkci zůstane stará verze a v rozhranní Gitlab CI uvidíme, co se stalo.

A na vývojovém stroji, jak rozhodnu, že budu načítat neminifikované verze?
To se detekuje v PHP, v šablonách pak máme něco jako {if $productionMode}...{else}...{/if}.

A proč ne i s CSS? Nechci hromadu souborů CSS, chci třeba skupinku CSS - opět dva seznamy.
Tohle moc nechápu. Naše řešení je, že při vývoji máme hromadu souborů načítaných přes @import v nějakém index.css, na produkci je jeden CSS soubor vytvořený kompilací toho index.css (resp. index.less).

„Stavím na řešení volání jediného css a js souboru.“
To mi nepřijde správné, protože když includuješ třeba 30 JS souborů a a třeba jen opravíš překlep, proč budeš nutit všechny, aby si stáhli celý balík souborů znovu? To je zbytečné.
Díky minifikaci ten soubor nebude nijak velký a pokud jde o výkon, tak je podstatnější počet requestů, než celková velikost stahovaných dat.
peta
Profil
[#9] joe - Proc? Prozen kod programem, ktery ti tam prislusne znacky doplni nebo upozorni na mozne problemy. Pripadne total commander ma moznost vyznacit zmeny v souboru proti jinemu souboru.
joe
Profil
llook:
To se detekuje v PHP, v šablonách pak máme něco jako {if $productionMode}...{else}...{/if}.
To je právě i to, o co mi šlo - takže máš dva seznamy. Už předvídám ty chyby, že se načítání souboru připíše na neprodukční verzi, ale po pushnutí na serveru nic nepřibyde (zapomene se na úpravu gruntfile). Líbilo by se mi to mít sjednocené a seznam mít jen jeden. Asi by šlo i nějak nechat generovat gruntfile.

Alphard:
Jde-li o chyby při minifikaci, nemám zkušenosti, ale co třeba hned při commitu zkusit provést (a výsledek zahodit)? Když to projde, je to ok a půjde to i později.
To beru jako dobrý nápad, vlastně jsem něco takového čekal, jen jsem nemyslel to "a zahodit". Mohlo by to tak před každým commitem kontrolovat, zda jsou data v commitu v pořádku a informovat o stavu.

Tohle moc nechápu. Naše řešení je, že při vývoji máme hromadu souborů načítaných přes @import v nějakém index.css, na produkci je jeden CSS soubor vytvořený kompilací toho index.css (resp. index.less).
Máte to řešené tak, že i na produkci je možné načíst neminifikované soubory? Pro ladění, úpravu CSS , ... v neminifikovaných úpravách se přece provádí kontrola a debugování jednodušeji :)
To s tím jedním CSS souborem se mi líbí.

Díky minifikaci ten soubor nebude nijak velký a pokud jde o výkon, tak je podstatnější počet requestů, než celková velikost stahovaných dat.
Myslíš, že tedy bude lepší minifikovat vše dohromady a nějaké balíky souborů (skupinky souborů) neřešit? I v případě, že třeba je web dost navštěvovaný? Nevznikne tak zbytečná zátěž na server, kdy třeba místo jednoho menšího změněného souboru, by se měl načítat znovu jeden velký? I v případě, že tam chodí třeba 10 tisíc návštěvníků?

peta:
Prozen kod programem, ktery ti tam prislusne znacky doplni nebo upozorni na mozne problemy.
Jaký nástroj mi doplní JavaScript? Znám jen pro kontrolu - JSLint / JSHint a i samotné Netbeans mi napovídají, kde mám "chybu" v kódu a doporučují úpravu.
Medvídek
Profil
Mam to řešené tak, že se minifikovaná verze (js, css i html) udělá až při odesílání ke klientovi. Tedy fyzicky jsou soubory neminifikované.
joe
Profil
Medvídek:
A ani soubory nikde nekešuješ? To se mi zdá pak docela náročné a může dojít k chybám, ...
Medvídek
Profil
joe:
Soubory jsou samozřejmě cachované, všechny js i css mají tvar main-1375609130.css. Čili commitem se změni timestamp a uživatelé si stáhnou nový soubor. Provozuji to takto 2 roky a zatím k žádné chybě nedošlo.
llook
Profil
joe:
To je právě i to, o co mi šlo - takže máš dva seznamy. Už předvídám ty chyby, že se načítání souboru připíše na neprodukční verzi, ale po pushnutí na serveru nic nepřibyde (zapomene se na úpravu gruntfile). Líbilo by se mi to mít sjednocené a seznam mít jen jeden. Asi by šlo i nějak nechat generovat gruntfile.
U CSS máme jeden seznam - index.less. Ten slouží jednak jako jediný stylopis, který načítám při vývoji (a kompiluje se v prohlížeči, což při vývoji tolik nevadí) a zároveň slouží jako ten seznam pro kompilaci (resp. v Gruntfile mám v seznamu pouze tento jeden soubor, ostatní se najdou přes @import).

Dva seznamy máme u JS a ten problém si uvědomuji. Není to ale primárně můj problém, je to problém frontendistů... Dá se to řešit podobně, jako u CSS, na vývoji načítat pouze jeden skript, který bude zároveň sloužit jako "seznam" pro kompilaci.

Myslíš, že tedy bude lepší minifikovat vše dohromady a nějaké balíky souborů (skupinky souborů) neřešit? I v případě, že třeba je web dost navštěvovaný?
Přesně tak. Dělá to tak i Seznam, Gmail, Google Docs...
joe
Profil
llook:
a kompiluje se v prohlížeči, což při vývoji tolik nevadí
Mně osobny by to třeba vadilo, pokud myslíš kompilaci Lessu třeba při každém požadavku (např. v PHP), tak to je hrozně pomalé a otravné. Na to je pak dobrý prográmek Simpless, který hlídá změny v souborech a po změně ihned kompiluje.

Dva seznamy máme u JS a ten problém si uvědomuji. Není to ale primárně můj problém, je to problém frontendistů...
Já dělám na frontendu, proto se o to zajímám :-) Na 99 % jsem našel řešení, v Gruntfile.js lze volat grunt.file.readJSON(), která načte JSON soubor. V šablonovacím systému pak můžu tento JSON soubor načíst taky a z něj vypsat ty soubory, které chci - všechny v případě vývoje a nebo jen jeden na produkci.

(je možné si udělat vlastní makro, například {jsFiles} - tím tedy bude jenom jeden seznam souborů a nevzniknou žádné problémy se synchronizací)

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: