Představuji Nette Assets pro správa statických souborů s integrací Vite

David Grudl
Nette Core | 8284
+
+16
-

Ahoj,

štval mě na různých projektech fragmentovaný přístup k assetům – měl jsem Vite pro frontend buildy, různé helpery pro obrázky, custom řešení pro thumbnaily, jiný systém pro OG images, na některých projektech ještě WebPack atd.

A samozřejmě řadu projektů, kde jsem verzoval assety ručně:

<link rel="stylesheet" href="{$baseUrl}/css/style.css?v=7">
<img src="{$baseUrl}/images/logo.png?v=1699123456" width="200" height="100" alt="Logo">

Tak jsem napsal jednotný systém pro všechny statické soubory. Malý, elegantní, s možností neomezeného rozšíření:

S Nette Assets se stejný kód změní na toto:

{asset 'css/style.css'}
<img n:asset="images/logo.png" alt="Logo">

Funguje to dokonce úplně bez konfigurace. Hned po instalaci můžete začít používat:

{asset 'logo.png'}     {* najde /www/assets/logo.png *}
{asset 'style.css'}    {* najde /www/assets/style.css *}
{asset 'app.js'}       {* najde /www/assets/app.js *}

Pokud máte soubory jinde než v /www/assets/, stačí jedna řádka:

assets:
    mapping:
        default: static  # soubory v /www/static/

Nativní Vite integrace s HMR

Moderní frontend vývoj bez Vite si neumím představit. Proto má Nette Assets first-class podporu včetně Hot Module Replacement!

Stačí minimal config:

vite.config.ts:

import { defineConfig } from 'vite';
import nette from '@nette/vite-plugin';

export default defineConfig({
    plugins: [nette()],
    build: {
        rollupOptions: {
            input: 'assets/main.js',
        },
    },
});

common.neon:

assets:
    mapping:
        default:
            type: vite
            path: assets

V šablonách používáte stejný kód:

{asset 'app.js'}

V development se automaticky načítá z Vite dev serveru s HMR.
V production se načítají optimalizované buildy.

Flexibilní Latte integrace

Knihovna poskytuje tři způsoby použití:

{* Kompletní HTML element *}
{asset 'hero.jpg'}

{* Plná kontrola nad HTML *}
<img n:asset="product.jpg" alt="Product" class="rounded">

{* Maximální flexibilita *}
{var $logo = asset('logo.png')}
<img src={$logo} width={$logo->width} height={$logo->height}>

…A spousta dalších feature

Budu rád za zpětnou vazbu, testování, bugreporty nebo nápady na vylepšení!

mystik
Člen | 320
+
0
-

Na prvni pohled se mi to libi. Jde nejak predavat tomu generatoru assets parametry? Konkretne by se mi treba hodila moznost nechat si vygenerovat nahled obrazku s konkretnimi rozmery.

MajklNajt
Člen | 516
+
0
-

https://blog.nette.org/…nette-assets#…

getAsset má parameter $options, s tým by sa to malo dať zmáknuť

David Grudl
Nette Core | 8284
+
+1
-

@mystik na tohle je v tom blogpostu ukázka

medhi
Generous Backer | 257
+
0
-

Ahoj, díky moc za tuhle věc, vypadá to naprosto skvěle, něco takového mi chybělo jako poslední puzzle celé Nette skládačky.

Narazil jsem ale zatím na tyto problémy:

  1. Z konfigurace Nette (http: csp) jsem musel:
    • ze style-src odebrat nonce a přidat unsafe-inline
    • do connect-src přidat 'ws://localhost:5173'

, jinak jsem dostával CSP violation.

  1. EDIT: nalezl jsem příčinu: https://github.com/…/Helpers.php#L134 timeout je tam 0, když dám 1 a více, už to funguje.

https://github.com/…ets/issues/1

Původní problém:

Nějak divně se mi detekuje development mód. Vše bych měl mít nastaveno správně, ale vite-plugin se aktivuje úplně náhodně při refreshování stránky tak v 10% případů… vůbec netuším s čím to může souviset.. nějaké kešování?

Projekt běží na localhost:8005, vite dev aktivní na localhost:5173, obojí na http. V 90% se natahují buildované soubory

<script src="http://localhost:8005/assets/app-Daee5PCB.js" type="module" crossorigin></script><link rel="stylesheet" href="http://localhost:8005/assets/app-DdsAdNXv.css" crossorigin>

v 10% se načte správně <script src="http://localhost:5173/app.js" type="module"></script><script src="http://localhost:5173/&#64;vite/client" type="module"></script>

Zkoušeno v Brave, Chrome, Firefox

Editoval medhi (11. 6. 14:48)

Felix
Nette Core | 1271
+
0
-

Vypada to skvele, urcite to zkusim nahradit za to co pouzivam ja (contributte/ui a contributte/vite) a pripadne to zarchivujeme. :-)

David Grudl
Nette Core | 8284
+
+5
-

Přidal jsem podporu pro nonce.

VáclavČerný
Člen | 6
+
0
-

Ahoj, super práce, něco takového tu chybělo, díky!

Zkusil jsem se rovnou zbavit Webpacku a to se mi i relativně snadno povedlo. Narazil jsem jen na jeden problém u Vite + Sass. Nastavil jsem .scss soubor přímo jako samostatný entry point a použil ho skrze {assets} makro. V produkčním buildu vše funguje podle očekávání, nicméně při použití dev serveru to končí chybou This asset type cannot be rendered as HTML., protože .scss se nevyhodnotí jako StyleAsset. Pokud jako quick fix přidám ExtensionToMime 'scss' => 'text/css', vše funguje krásně i v dev módu a to včetně HMR.

Dá se tohle nějak vyřešit?
Díky.

David Grudl
Nette Core | 8284
+
0
-

@VáclavČerný fixed

VáclavČerný
Člen | 6
+
0
-

@DavidGrudl Funguje, paráda, díky!

MaN8fy
Člen | 2
+
0
-

Ahoj,

řeším integraci s Dockerem. Vše mám nastavené tak, aby vývoj probíhal přes reverzní proxy (nginx-proxy), takže jednotlivé služby mají své domény (app.localhost, adminer.localhost, vite.localhost, atd.).

Mám:

  • vite.config.js
export default defineConfig({
    server: {
        host: '0.0.0.0',
        port: 5173,
        origin: 'http://vite.localhost:5173',
        watch: {
            usePolling: true,
        },
    },
    plugins: [
        nette(),
    ],
});
  • docker-compose.yml (výběr relevantních služeb)
services:
    proxy:
        image: jwilder/nginx-proxy
        ports:
            - "80:80"
        volumes:
            - /var/run/docker.sock:/tmp/docker.sock:ro
        networks:
            - skeleton-net

    vite:
        image: node:24-alpine
        user: "1000:1000"
        working_dir: /var/www
        volumes:
            - ./:/var/www
        command: >
            sh -c "npm install && npm run dev"
        ports:
            - "5173:5173"
        expose:
            - "5173"
        environment:
            VIRTUAL_HOST: vite.localhost
            VIRTUAL_PORT: 5173
        networks:
        - skeleton-net

Vite server běží správně – http://vite.localhost:5173/app.js je dostupné z prohlížeče.

Problém

Když v šabloně použiju {asset 'favicon.ico'}, @nette/vite-plugin ve vývojovém režimu vygeneruje: http://0.0.0.0:5173/favicon.ico

Namísto správného: http://vite.localhost:5173/favicon.ico

Zkoušel jsem

  • změnit server.host z ‚0.0.0.0‘ na ‚vite.localhost‘ – Vite server pak přestal úplně fungovat (nebyl přístupný zvenku),
  • přidat server.origin – bez efektu,
  • přidat server.hmr s nastavením host, clientPort, protocol, atd. – bez efektu.

Existuje nějaký způsob, jak přimět @nette/vite-plugin, aby generoval ve vývojovém režimu správnou adresu assetů – tedy vite.localhost:5173 místo 0.0.0.0:5173?

Případně – je potřeba plugin nějak speciálně konfigurovat, aby to fungovalo s reverzní proxy (jwilder/nginx-proxy)? Vite sám o sobě běží správně…

Editoval MaN8fy (9. 7. 10:15)

jeremy
Člen | 58
+
+1
-

@MaN8fy

Uz je na to PR: https://github.com/…lugin/pull/2

Zatim muzes nastavit devServer url v configuraci nette assets

assets:
    mapping:
		...
		devServer: vite.localhost:5173

Editoval jeremy (9. 7. 17:27)

MaN8fy
Člen | 2
+
0
-

Díky, pomohlo.
Edited: misinformation

Editoval MaN8fy (10. 7. 10:51)