Jednolita dystrybucja HTML, JS oraz CSS

0

Jest plik HTML, ileś plików JS, obrazków, CSS, które mogą być w formie osobnych plików, a można zawrzeć w samym HTML. Na przykład ta gra mojego autorstwa https://github.com/andrzejlisek/Roulette to jest jeden HTML i wiele plików JS, bo tak łatwiej nad tym pracować (poprawki błędów, ulepszenia), niż mieć jeden ogromny plik HTML.

Czy istnieje znane i sprawdzony program (jeśli tak, to jaki), który wykonuje następującą czynność: Wskazuje się plik HTML, program wczyta wszystkie pliki wskazane w tym HTML, a następnie te odniesienia plików zastąpi treścią pliku w samym HTML. Na przykład, znacznik <script src="file.js"></script> zamieni na <script>tekst_z_pliku_file.js</script>. Można tak zrobić z plikami JS, CSS i obrazkami. Finalnie byłby pojedynczy HTML, który zawiera wszystko w sobie. Lepszy program, oprócz tej czynności jeszcze mógłby dokonać minifikacji finalnego pliku.

Jak się nazywa po angielsku opisana czynność? Myślałem, że "merge", ale jak szukałem w Google pod tą nazwą, to nic nie znalazłem. Słowo "preprocessor" nie sugeruje tej czynności, mimo, że w C++ preprocesor wykonuje analogiczną czynność (zamienia znaczniki #include file.h zawartością wskazanego pliku) dostając finalnie jeden plik cpp przekazywany do kompilatora, ale to nie jedyna czynność.

Zakładam, że jestem nie pierwszy i nie ostatni, który chciał zautomatyzować dokonanie tej czynności.

4

Szukaj pod hasłem "js bundle" albo "js bundler", ja używam Webpack.

W webpacku jest opcja inlineowania skryptów w HTML, i wtedy możesz mieć jeden wynikowy .html ze wszystkim, dodatkowo mógłbyś zminifikować css i js

2

Ale takie pytanie - to jest forum dla programistów, Ty prawdopodobnie się też za takiego uważasz. Zresztą - stworzyłeś jakąś grę, dajesz link do niej, nawet wiesz co to jest github. Więc powinieneś wiedzieć, że napisanie czegoś takiego samodzielnie to kilka(naście) minut. Chyba, że chodzi Ci o coś bardziej skomplikowanego, ale z tego co rozumiem to ma przelecieć przez plik HTML i w miejscach, w których znajdzie odniesienia w stylu <script src="file.js"> ma wstawić zawartość tego pliku. Jeśli tak, to serio - sam byś to ogarnął prędzej/szybciej, niż potrzebowałeś czasu na założenie wątku tutaj, przeczytanie odpowiedzi, poszukanie wskazanych programów czy rozwiązań oraz obczajenie, jak one działają.

1

Dziś się odchodzi od webpacka na rzecz https://vitejs.dev

1
cerrato napisał(a):

Ale takie pytanie - to jest forum dla programistów, Ty prawdopodobnie się też za takiego uważasz. Zresztą - stworzyłeś jakąś grę, dajesz link do niej, nawet wiesz co to jest github. Więc powinieneś wiedzieć, że napisanie czegoś takiego samodzielnie to kilka(naście) minut. Chyba, że chodzi Ci o coś bardziej skomplikowanego, ale z tego co rozumiem to ma przelecieć przez plik HTML i w miejscach, w których znajdzie odniesienia w stylu <script src="file.js"> ma wstawić zawartość tego pliku. Jeśli tak, to serio - sam byś to ogarnął prędzej/szybciej, niż potrzebowałeś czasu na założenie wątku tutaj, przeczytanie odpowiedzi, poszukanie wskazanych programów czy rozwiązań oraz obczajenie, jak one działają.

Tak, ja uważam się za programistę, również chętnie korzystam z www.google.com ale nie zawsze z zamierzonym skutkiem, nawet ja już opracowałem takie narzędzie na własne potrzeby (wstawia zawartość skryptów, stylów i obrazków) i z niego korzystam (a to, że nie ma go na moim Githubie, to już inna bajka). Niedawno w bardziej skomplikowanym projekcie niż ta gra, objawił drobny błąd (konwersja się dokonała, ale finalny plik HTML nie działał). Z jednej strony, to dla mnie żaden problem zdebugować i poprawić swoje narzędzie, ale z drugiej strony, nie zaszkodzi zapytać na forum, czy istnieje jakieś popularne i gotowe, które z pewnością będzie dużo lepsze niż moje.

3
cerrato napisał(a):

Jeśli tak, to serio - sam byś to ogarnął prędzej/szybciej, niż potrzebowałeś czasu na założenie wątku tutaj, przeczytanie odpowiedzi, poszukanie wskazanych programów czy rozwiązań oraz obczajenie, jak one działają.

z drugiej strony - to w społeczności JS już rozwiązany problem, więc czemu robić coś partyzancko, zamiast użyć tego, czego używa społeczność (np. Webpack, chociaż ja preferuję Esbuild)?

Chociaż patrząc po Githubie to jest kod, który nie używa żadnych modułów (a to błąd, nawet bez bundlera można już używać modułów ES6, bo przeglądarki już to obsługują: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import ), więc też nie wiem, jak bundlery sobie z tym poradzą (chociaż pewnie kwestia ustalenia odpowiednich opcji w konfiguracji. No ale IMO lepiej to najpierw przepisać na moduły, żeby pisać jak człowiek, a potem dorzucić bundler)

0
LukeJL napisał(a):
cerrato napisał(a):

Jeśli tak, to serio - sam byś to ogarnął prędzej/szybciej, niż potrzebowałeś czasu na założenie wątku tutaj, przeczytanie odpowiedzi, poszukanie wskazanych programów czy rozwiązań oraz obczajenie, jak one działają.

z drugiej strony - to w społeczności JS już rozwiązany problem, więc czemu robić coś partyzancko, zamiast użyć tego, czego używa społeczność (np. Webpack, chociaż ja preferuję Esbuild)?

Właśnie przyjęcie założenia, że taki problem jest rozwiązany sprawiło, ze postanowiłem założyć ten wątek i dowiedzieć się, czego używa społeczność. Właśnie zostało wymienionych kilka narzędzi i o to chodziło. W mojej gestii jest ich przetestowanie i stwierdzenie, które odpowiadają moim potrzebom.

Chociaż patrząc po Githubie to jest kod, który nie używa żadnych modułów (a to błąd, nawet bez bundlera można już używać modułów ES6, bo przeglądarki już to obsługują: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import ), więc też nie wiem, jak bundlery sobie z tym poradzą (chociaż pewnie kwestia ustalenia odpowiednich opcji w konfiguracji. No ale IMO lepiej to najpierw przepisać na moduły, żeby pisać jak człowiek, a potem dorzucić bundler)

Do samego wykonania kodu nie jest potrzebny żaden bundler. Bundler jest potrzebny tylko do tego, zeby z wielu małych plików zrobić jeden duży plik robiący dokładnie to samo. A nie jest przypadkiem dokładnie odwrotnie niż piszesz? Jeżeli kod jest bez modułów, to wystarczy bardzo prosty algorytm pracujący na HTML, który nie analizuje samych skryptów JS, żeby dostać pojedynczy plik (każde doniesienie do pliku JS zastąpić samym plikiem i to wszystko). Natomiast, jak przerobię kod na moduły, to okaże się, że dodatkowo potrzebna jest analiza skryptów JS, żeby wychwycić każdą instrukcję import, zinterpretować nazwę pliku w parametrze, żeby w miejsce tej instrukcji wstawić wskazany plik JS. Moim zdaniem, analiza JS algorytmicznie jest trudniejsza niż analiza HTML.

Nic nie stoi na przeszkodzie, żeby samemu sprawdzić, ale wydaje się, że o ile prosty bundler poradzi sobie z HTML, o tyle nie poradzi sobie z samym JS (import modułów). Chyba, że jest to bundler specjalizowany do samego JavaScript, to może nie mieć nawet możliwości łączenia JS i HTML.

2

@andrzejlisek Sprawdziłem pobieżnie jeden plik z twojego repo. NIe używaj var tylko let i const. Zamiast getElementById masz querySelector. Otworzyłem tylko 1 plik i zbytnio na niego nie patrzyłem, ale te 2 rzeczy mi się rzuciły w oczy

1

z tym, żeby nie używać var to się zgodzę, ale czemu getElementById miało by być gorsze niż querySelector, jeśli chce się wydobyć id?

poza tym styl. Zwyczajowo zamiast:

function DisplayHelp()
{

większość programistów JSa napisze to tak:

function displayHelp() {

bo tak się przyjęło.

Tylko to trzeba byłoby zamieniać totalnie wszystko, więc może w tym przypadku darować sobie tę zmianę.

0

Jakby się przyjrzeć, to zapewne jest jeszcze wiele innych rzeczy do poprawy. Co do var, let i const, to się zgodzę, bo czytałem, ze przeglądarki kontrolują wielokrotną deklacaję let, a nie kontrolują var. Co do getElementById i querySelector to pobieżnie poszukałem i widzę, że querySelector ma większe możliwości wyszukiwania, choć jedno i drugie potrafi znaleźć po Id z równie dobrym skutkiem i nie znalazłem informacji, które jest lepsze do tego i dlaczego. Róznica jest, że jedno zwraca dynamiczną listę obiektów, a drugie statyczną. Jednak bez zmian w DOM polegających na dodawaniu i usuwaniu obiektów, nie rozumiem, co to za różnica.

Co do pisania {, to czemu "wszyscy" piszą w tej samej linii (bo tak rozumiem, co napisał LukeJL)? Moim zdaniem napisanie w następnej linii zwiększa czytelność, bo jak klamra otwierająca i zamykająca jest tak samo odległa od lewego brzegu, to od razu widać, gdzie się zaczyna i kończy objęty nią fragment kodu, nawet wtedy gdy cały blok się nie mieści. Tutaj różnie popularne sposoby: https://en.wikipedia.org/wiki/Indentation_style . Jeżeli na szerszą skalę przyjął się styl K&R to musi być lepszy lub bardziej czytelny od stylu Allman, który ja zastosowałem. A moim zdaniem jest dokładnie odwrotnie, jak przerobię jakiś cudzy kod z K&R do Allman to wydaje się, że zyskuję na przejrzystości, a nie tracę.

0
ehhhhh napisał(a):

Dziś się odchodzi od webpacka na rzecz https://vitejs.dev

Jeśli chcesz pisać takie posty, to podaj kilka argumentów merytorycznych za tym.

0

Co do pisania {, to czemu "wszyscy" piszą w tej samej linii (bo tak rozumiem, co napisał LukeJL)? Moim zdaniem napisanie w następnej linii zwiększa czytelność

Moim zdaniem dawanie klamry otwierającej w osobnej linii to marnowanie tej linijki na ekranie. Ona powinna być na końcu poprzedniej linii. A wizualnie blok wyróżni wcięcie.

0

@Riddle: @LukeJL , @cerrato Kiedyś na CR miałem info, aby się na jedno zdecydować. Osobiście też tak wolę pisać ze względu na moją wygodę. Fakty być może uwaga nie trafiona

1

@Riddle: Bardzo proszę. Laravel przeszedł na vite rok temu, duże paczki templatek/szkieletów pod vue/angulara dostepne na themeforest z których zdarza mi się korzystać również przechodzą na vite. Z tego co widzę pod spodem ma to esbuilda czyli to co proponuje @LukeJL

0

@ehhhhh:

No to popatrz sobie na instalacje z ostatniego tygodnia:

screenshot-20230311134748.png
screenshot-20230311134757.png

Co do tej "popularności", to też jeszcze nie wiem czy mamy jakiś efekt. Faktycznie vite zwiększa popularność, i webpack trochę spada, no ale to jeszcze nie jest nic "wow".

screenshot-20230311134015.png+

1

@Riddle: javy też się nie da usunąć ze świata w jeden dzień :) Natomiast polemizujesz cały czas z suchym faktem który podałem i który sam potwierdzasz że jest prawdziwy tylko dlatego, żeby się wybielić. Polecam trochę pokory i odwagi przyznania się do błędu, bo póki co walczysz z problemem który sam stworzyłeś.

0

@Riddle: marna podwójna manipulacja. Nike nie wpisuje bundle jak szuka vite lub webpacka

screenshot-20230311142521.png

1
anonimowy napisał(a):

@Riddle: marna podwójna manipulacja. Nike nie wpisuje bundle jak szuka vite lub webpacka

W screenie który Ty wkleiłeś widać że w marcu 2018 roku vite był dwa razy popularniejszy od webpacka. Niby spoko, tylko że pierwszy release vite był w kwietniu 2020, a pierwsze commity w 2019 :> Więc jak to możliwe, ludzie go używali zanim powstał? :>

Szkoda że tak bezkrytycznie wrzuciłeś pierwszy lepszy screen i potencjalnie wprowadziłeś forumowiczów w błąd.

Odpowiedzią na to jest to że samo słowo "Vite" jest używane też w innych kontekstach, np w podręcznikach do francuskiego, i to głównie te inne konteksty nabijają trend który pokazałeś. Dopisanie "bundle" pokazuje bardziej miarodajne wartości bo chociaż trochę ograniczają wyszukiwania do programowania. Samo "vite" i "webpack" jest niemiarodajne, bo "vite" nie jest na tyle unikalnym słowem żeby tak to zmierzyć.

A nawet jeśli to Ci się nie podoba, to możemy olać google trends, i kierować się jedynie weekly downloads z npm'a, w których widać różnicę rzędu wielkości.

Odchodzimy od tematu

Cały mój temat wziął się stąd, że padła odpowiedź u góry, polecająca vite nad webpack - i poprosiłem o merytoryczny argument za tym; a dostaliśmy tylko argument ad populum.

Cały mój udział w tym wątku miał być tylko nakłonieniem odpowiadających do merytorycznych argumentów; a nie argumentów w stylu "laravel tego używa więc to musi być lepsze".

0

@Riddle: znowu gadasz głupoty. Wskaż mi dokładnie gdzie polecałem vite i gdzie podałem, że jest lepszy od webpacka?

0

Napisałem prymitywną apkę w HTML/JS, taką, która wykonuje podstawowe działania na dwóch liczbach, żeby przetestować bundlery, jakie mi proponujecie.

Ponieważ nie znam modułów ES6, na szybko poczytałem jak się je robi i mam apkę z dwoma skryptami JS. Jeden skrypt jest bez modułów i działa poprawnie, a drugi wykorzystuje moduł i nie działa w ogóle (nic się nie dzieje po kliknięciu przycisku), przeglądarka Firefox w konsoli wypisuje takie komunikaty:

Zablokowano żądanie do zasobu innego pochodzenia: zasady „Same Origin Policy” nie pozwalają wczytywać zdalnych zasobów z „file:///media/xxx/WORK1/__ToBackup/Develop/HTML/HtmlBundle/App2.js” (żądanie CORS inne niż HTTP).

URI źródła modułu jest niedozwolony w tym dokumencie: „file:///media/xxx/WORK1/__ToBackup/Develop/HTML/HtmlBundle/App2.js”.

TestHtml.zip

Co jest w tej aplikacji źle zrobione i muszę poprawić, lub jak skonfigurować Firefoxa (chociaż konieczność specjalnego konfigurowania przeglądarki pod konkretną aplikację jest złym pomysłem), żeby skrypt z modułem działał poprawnie?

Jakie tu jest nieprzestrzeganie "same origin policy", skoro wszystkie pliki są w jednym i tym samym folderze?

0
Riddle napisał(a):

Cały mój temat wziął się stąd, że padła odpowiedź u góry, polecająca vite nad webpack - i poprosiłem o merytoryczny argument za tym; a dostaliśmy tylko argument ad populum.

Albo w tym momencie pokazuejsz dowód, że ktoś tutaj tak napisał albo daj sobie ostrzeżenie za kłamstwo i manipulację. Vite rośnie kilkukrotnie (procentowo) bardziej niż webpack.

0

@andrzejlisek

<script type="module" crossorigin src="/script.js"></script>
0
ehhhhh napisał(a):

@andrzejlisek

<script type="module" crossorigin src="/script.js"></script>

W ten sposób?

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="Style.css">
  </head>
  <body>
    <img src="Img.png"><br>
    <span class="C1">Number 1</span><input type="text" size="4" id="Num1" value="3"><br>
    <span class="C2">Number 2</span><input type="text" size="4" id="Num2" value="2"><br>
    <button onclick="AddSub()">Add, subtract</button><br>
    <button onclick="MulDiv()">Multiply, divide</button><br>
    <span id="NumResult1"></span><br>
    <span id="NumResult2"></span><br>
    <script src="App1.js"></script>
    <script src="App2.js" crossorigin type="module"></script>
  </body>
</html>

Próbowałem crossorigin, crossorigin="", crossorigin="anonymous" i w każdym przypadku mam te same komunikaty, co przed zmianą.

Zainstalowałem i uruchomiłem to https://addons.mozilla.org/en-US/firefox/addon/cors-everywhere/ , również nie rozwiązało problemu.

@anonimowy: Chodzi o to, żeby skrypt działał i online, czyli z serwera, i offline, czyli plik wgrany do komputera lub telefonu. W związku z tym, rozwiązanie, które działa tylko online to tak sobie. Nie szkodzi, że 99% apek HTML/JS działa online.

0
andrzejlisek napisał(a):

@anonimowy: Chodzi o to, żeby skrypt działał i online, czyli z serwera, i offline, czyli plik wgrany do komputera lub telefonu. W związku z tym, rozwiązanie, które działa tylko online to tak sobie. Nie szkodzi, że 99% apek HTML/JS działa online.

Ale Ty mówiąc "działał offline" masz na myśli to, że uruchomisz tą stronę np http://localhost:8080/index.html? Czy chodzi Ci o to że otworzysz ją jak goły plik file:///C:\Users\andrzej\projekt\index.html?

Bo jeśli to drugie, to to nie ma prawa działać.

0
Riddle napisał(a):
andrzejlisek napisał(a):

@anonimowy: Chodzi o to, żeby skrypt działał i online, czyli z serwera, i offline, czyli plik wgrany do komputera lub telefonu. W związku z tym, rozwiązanie, które działa tylko online to tak sobie. Nie szkodzi, że 99% apek HTML/JS działa online.

Ale Ty mówiąc "działał offline" masz na myśli to, że uruchomisz tą stronę np http://localhost:8080/index.html? Czy chodzi Ci o to że otworzysz ją jak goły plik file:///C:\Users\andrzej\projekt\index.html?

Bo jeśli to drugie, to to nie ma prawa działać.

Mam na myśli plik file:///C:\Users\andrzej\projekt\index.html.

Umieściłem na swoim githubie;
https://andrzejlisek.github.io/HtmlBundle/Index.html
https://github.com/andrzejlisek/andrzejlisek.github.io/tree/main/HtmlBundle
Już nie mam komunikatu o polityce tego samego pochodzenia.

Teraz jest taki problem, ze przeglądarka "nie widzi" żadnej funkcji z pliku "App2.js". Są trzy wersje funkcji MulDiv. Ostatnia z nich to na wzór tego: https://www.freecodecamp.org/news/modules-in-javascript/

W praktyce, żadna funkcja nie działa, przeglądarka zgłasza, że funkcja nie jest zdefiniowana.

Co tym razem jest nie tak?

0
andrzejlisek napisał(a):
Riddle napisał(a):
andrzejlisek napisał(a):

@anonimowy: Chodzi o to, żeby skrypt działał i online, czyli z serwera, i offline, czyli plik wgrany do komputera lub telefonu. W związku z tym, rozwiązanie, które działa tylko online to tak sobie. Nie szkodzi, że 99% apek HTML/JS działa online.

Ale Ty mówiąc "działał offline" masz na myśli to, że uruchomisz tą stronę np http://localhost:8080/index.html? Czy chodzi Ci o to że otworzysz ją jak goły plik file:///C:\Users\andrzej\projekt\index.html?

Bo jeśli to drugie, to to nie ma prawa działać.

Mam na myśli plik file:///C:\Users\andrzej\projekt\index.html.

Umieściłem na swoim githubie;
https://andrzejlisek.github.io/HtmlBundle/Index.html
https://github.com/andrzejlisek/andrzejlisek.github.io/tree/main/HtmlBundle
Już nie mam komunikatu o polityce tego samego pochodzenia.

Teraz jest taki problem, ze przeglądarka "nie widzi" żadnej funkcji z pliku "App2.js". Są trzy wersje funkcji MulDiv. Ostatnia z nich to na wzór tego: https://www.freecodecamp.org/news/modules-in-javascript/

W praktyce, żadna funkcja nie działa, przeglądarka zgłasza, że funkcja nie jest zdefiniowana.

Co tym razem jest nie tak?

No nie tak jest właśnie to że otwierasz go jako file:///.

Powinieneś postawić lokalny server i odpalić apke np localhost:8080. Możesz użyć wbudowanego servera w pythona, php lub node'a; albo wykorzystać devServer z webpacka. Jeśli chcesz wyciągać na prawdę grube armaty (nie polecam) to możesz postawić kontener z nginx apachem na dockerze; a jeśli chcesz na prawdę kobyłę to możesz zainstalować Lamp/Wamp lokalnie - ale to ostatnie to już mega overkill.

0
Riddle napisał(a):

No nie tak jest właśnie to że otwierasz go jako file:///. Powinieneś postawić lokalny server i odpalić apke np localhost:8080. Możesz użyć wbudowanego servera w pythona, php lub node'a; albo wykorzystać devServer z webpacka.

Rozumiem. Dlatego wrzuciłem na GitHub, bo to już jest prawdziwy serwer.
https://andrzejlisek.github.io/HtmlBundle/Index.html
https://github.com/andrzejlisek/andrzejlisek.github.io/tree/main/HtmlBundle

Czy postawię własny serwer, czy będę korzystać z GitHub to chyba nie ma znaczenia. Teraz jest pytanie, gdzie jeszcze jest błąd w samym projekcie.

1
andrzejlisek napisał(a):
Riddle napisał(a):

No nie tak jest właśnie to że otwierasz go jako file:///. Powinieneś postawić lokalny server i odpalić apke np localhost:8080. Możesz użyć wbudowanego servera w pythona, php lub node'a; albo wykorzystać devServer z webpacka.

Rozumiem. Dlatego wrzuciłem na GitHub, bo to już jest prawdziwy serwer.
https://andrzejlisek.github.io/HtmlBundle/Index.html
https://github.com/andrzejlisek/andrzejlisek.github.io/tree/main/HtmlBundle

Czy postawię własny serwer, czy będę korzystać z GitHub to chyba nie ma znaczenia. Teraz jest pytanie, gdzie jeszcze jest błąd w samym projekcie.

Postawienie servera developerskiego lokalnie jest bardzo proste

Python:

cd project/
python -m http.server

PHP:

cd project/
php -S localhost:8080
0

Poradziłem sobie, serwer php usprawnił pracę, na HitHub też działa, było jeszcze parę innych błędów, które sam poprawiłem i moduł zadziałał.

0

Zacząłem w końcu testować te bundlery, opisuję wrażenia.

Do aplikacji testowej https://andrzejlisek.github.io/HtmlBundle/Index.html dodałem jeszcze skrypt z obiektem Worker, aby mieć trzy przypadki w jednym:

  1. Zwykły skrypt.
  2. Skrypt z modułem.
  3. Skrypt z workerem.

WebPack:
Znalazłem to
Jeszcze spróbuję powalczyć. To jakaś kobyła, wydaje się kłopotliwa w konfiguracji, trzeba tworzyć i edytować dodatkowy plik .json. Póki co, nie udało mi się przeprowadzić połączenia.

ESBuild:
Dokonałem instalacji wg https://esbuild.github.io/getting-started/

Ten program. potrafi zminifikować każdy skrypt, ale połączyć to chyba umie tylko moduły. W przypadku skryptu z Worker, nie dokonał połączenia. Trzeba podać skrypt JS jako parametr, żeby połączyć. Pliku HTML raczej nie umie połączyć.

ViteJS:
W pewnym stopniu to czego szukałem. W pliku z projektem musi być plik index.html , wystarczy podać polecenie npx vite build i program robi wszystko. Obrazek wrzucił do HTML, czyli dobrze, styl też przetworzył, ale wyrzucił do pliku, który nazwał po swojemu. Co do JS, to zadziałał tak sobie. Skryptu App1 i App3 w ogóle nie przetworzyć, a skrypt App2.js przetworzył, czyli połączył z modułem, czyli tu zadziałał.

Jeszcze będę walczyć, ale przy okazji zapytam: Czy uzyskane efekty działania dwóch ostatnich programów to kwestia konfiguracji czy ograniczonych możliwości tych programów?

Oczekiwane działanie jest proste: Podaję plik HTML, program wyczuwa wszystkie pliki towarzyszące (na podobnej zasadzie, jak zapisanie na dysku kompletnej strony w przeglądarce internetowej), a potem generuje autonomiczny plik HTML, który zawiera wszystko w sobie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1