Instalace frontend assetů pomocí Composeru
- janpecha
- Backer | 75
Ahoj všem,
napsal jsem plugin pro
Composer, který umožňuje vytáhnout statické soubory (CSS, JS,…) ze
složky /vendor
do složky /www
. Plugin stačí
nainstalovat jako závislost projektu a on pak automaticky při aktualizaci
balíčků aktualizuje i assety ve složce /www
.
K čemu je to dobré?
- můžete poslat Bower do věčných lovišť a instalovat frontend knihovny pomocí jednoho z nejlepších package managerů™
- pokud máte projekt jenom v PHP, můžete všechny závislosti spravovat na jednom místě
- server-side i client-side budou používat stejné verze knihoven (viz
nette/forms
vs.netteForms.js
) - při commitování
composer.lock
budete mít jistotu, že všechny frontend assety budou nainstalovány vždy ve správné verzi
S čím plugin nepomůže?
- neřeší spojování a kompilaci JS/CSS/LESS/… souborů – tohle každý řeší po svém a navíc pro tuhle činnost existuje dostatek jiných nástrojů
Instalace
composer require frontpack/composer-assets-plugin
Konfigurace
Konfiguraci lze rozdělit do 2 částí:
- konfigurace konkrétních balíčků – balíčky definují seznam souborů a složek, které bude plugin instalovat
- konfigurace projektu – programátor definuje, kam má plugin assety umístit
1) konfigurace konkrétních balíčků
Aby plugin věděl, které soubory má přetáhnout do složky
www/
, musí balíčky v composer.json
uvést jejich
seznam. Pro nette/forms
by to vypadalo nějak takto:
{
"name": "nette/forms",
"extra": {
"assets-files": [
"src/assets/netteForms.js"
]
}
}
Po instalaci nette/forms
se soubor netteForms.js
objeví v umístění assets/nette/forms/netteForms.js
.
2) konfigurace projektu
Změna složky s assety
Ve výchozím nastavení plugin nainstaluje soubory do složky
assets
hned vedle složky vendor
. To nemusí být
vždycky užitečné a tak je možné cílové umístění upravit. Stačí
v projektovém composer.json
nastavit konfigurační volbu
assets-dir
. Pro standardní strukturu Nette aplikace by nastavení
mohlo vypadat nějak tahle (cesta je relativní vzhledem k umístění složky
vendor
):
{
"config": {
"assets-dir": "www/assets"
}
}
Podpora pro nekompatibilní balíčky
Málokterý balíček obsahuje seznam souborů pro instalaci a tak plugin
umožňuje definovat tento seznam v projektovém
composer.json
:
{
"config": {
"assets-files": {
"nette/forms": [
"src/assets/netteForms.js"
],
"o5/grido": [
"assets/dist"
]
}
}
}
Díky tomu dokáže plugin pracovat i s nepodporovanými balíčky.
Nastavení uvedené v projektovém composer.json
má nejvyšší
prioritu, takže lze zcela přepsat seznam souborů poskytovaný konkrétními
balíčky.
Protože je otrava psát seznam souborů svépomocí, obsahuje plugin předpřipravený seznam souborů pro vybrané nekompatibilní balíčky, aktuálně pro:
components/jquery
nette/forms
o5/grido
Plugin je aktuálně ve verzi 0.9.1, budu rád, když ho vyzkoušíte a podělíte se o bug reporty, feature requesty a pull requesty :) Berte to zatím jako koncept.
Upozornění pro uživatele Windows – nemám plugin
otestovaný na Windows. Místo kopírování souborů plugin vytváří pouze
relativní symlinky do složky mělo by být vyřešenovendor/
– na Windows to
pravděpodobně nebude fungovat. Časem to plánuju vyřešit pomocí instalačních
strategií.
Editoval janpecha (7. 3. 2017 13:04)
- janpecha
- Backer | 75
Co když to nechci mít ve www, ale chci spojit assety v neveřejný složce?
Buď řekneš pluginu, že to má nahrát do nějaké jiné složky a tam si to nějak pořešíš, nebo prostě použiješ jiný vhodnější nástroj.
Navíc mi přijde, že se od assetů v composeru upouští a assety se hází na bower aj.
No vidíš, a já upouštím od instalace assetů pomocí „Boweru, aj.“ a hazím to na Composer :) Protože mi to tak u PHP projektů prostě více vyhovuje – Bower je skoro mrtvej, nemá lock soubor a nepřináší nic, co by mě donutilo ho nadále používat. Composer se mi dobře stará o PHP závislosti, proč by se dobře nepostaral i o ty ostatní.
- janpecha
- Backer | 75
Tak hlavně záleží, jak aktuálně s těmi assety pracuješ. Třeba u mě to vypadá takto:
- během vývoje mám assety ve složce
www/assets
, načítám je odsud - při buildu assety z
www/assets
pospojuju a na produkci nahrávám jen spojené soubory, složka www/assets se tak na server vůbec nedostane
Zároveň je diskutabilní, jestli opravdu potřebuješ při vývoji speciální nástroj, který se ti stará o spojování. Třeba LESS se dokáže spojovat sám o sobě, vč. úpravy relativních cest, JS soubory ti zase může spojovat Apache.
No a pokud potřebuješ něco komplexnějšího, prostě použiješ nějaký komplexnější nástroj – Webpack, či cokoli jiného.
- Tomáš Votruba
- Moderator | 1114
Ahoj, pěkná práce!
Nečetl jsem všechny features, ale jak bys to stručně porovnal s https://github.com/…asset-plugin
- janpecha
- Backer | 75
Vytvořím si soubory pro jednotlivá použití (admin.js, front.js, admin.less, front.less,…) a v nich uvedu seznam souborů, které se mají načíst. Pro strukturu
- www/
- assets/ – soubory nakopírované pomocí
composer-assets-plugin
- admin.js
- admin.less
- assets/ – soubory nakopírované pomocí
by to vypadalo třeba takhle:
admin.js
<!--#include file="assets/nette/forms/netteForms.js" -->
<!--#include file="assets/xyz/xyz/abc.js" -->
admin.less
@import 'assets/xyz/xyz/abc.less';
Teoreticky by šlo načítat ty JS a CSS/LESS soubory přímo ze složky
/vendor
, ve skutečnosti je to však nepraktické, protože stejně
musíš z /vendor
do /www
vykopírovat obrázky a
fonty, tak proč rovnou nevykopírovat všechno.
Při deploymentu pak nechám ten admin.js a admin.less zkompilovat a zminifikovat.
Jestli je lepší kopírovat soubory, nebo použít Webpack záleží na situaci:
- buď soubory kopíruješ a pak nepotřebuješ Webpack
- nebo použiješ Webpack a pak nepotřebuješ kopírovat soubory
Primárně tak záleží na tom, jestli Webpack využiješ i k něčemu jinému, než je spojování souborů.
- Ivorius
- Nette Blogger | 119
jako pro mě by byla ideální možnost mít něco ve stylu:
definice balíčku composer:
"extra": {
"assets": {
"front.js": [
"assets/front/search.js",
"assets/front/main.js",
],
"admin.js": [
"package/xxx.js"
]
}
}
Mno a pak už by se jen místo kopírování těch souborů vytvořily
soubory front.js a admin.js, kde by bylo např.
require(‚vendor/unio/algolia/assets/front/search.js‘);
require(‚vendor/unio/algolia/assets/front/main.js‘);