[SOLVED] Quasar build. Single inlined HTML file.
-
I want to build the web app as a single html file inlining css and js. Tried using HtmlWebpackPlugin but couldn’t get it to work. Is this possible this way, what am I doing wrong?
extendWebpack(cfg) { ... let HtmlWebpackPlugin = require('html-webpack-plugin'); let HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin'); cfg.plugins.push( new HtmlWebpackPlugin({ inlineSource: '.(js|css)$' })); cfg.plugins.push( new HtmlWebpackInlineSourcePlugin(HtmlWebpackPlugin) ); }
-
I would ask this question on the Discord channel.
-
@dobbel thanks, already solved It. Was a really long journey, but I’m very happy. I got my ui working on the esp32 and the result is quite satisfactory.
-
Great! Could you please post your solution?
-
Re: Quasar build. Single inlined HTML file.
OK. Let’s see. Why would anyone want to pack an SPA into a single, huge html file; that’s terrible for caching and it’s exactly what most people don’t want. Still I’ve found that this could be really useful for hosting any kind of webapp in small microcontroller like the ESP32. I thought it would be a great idea to revamp my dashboard using the power of Vue. So in couple of hours I made a new UI for my MCU using Quasar and went straight to serve it … to good to be true.
There are two popular webservers for ESP in Arduino. The good old synchronous WebServer and a new, progressive AsyncWebServer. First, I tried using the AsyncWebserver (asynchrony is great right?). This implementation is very good at handling simultaneous requests, like those made by any modern browser, the problem lies in the small RAM memory available in the ESP32 (64Kb in my devboard). This webserver serves everithing from memory once memory runs out it chunks the response, a thing that happens with 700Kb quasar runtime “vendor.js” . Circunventing this seemed like a lot of trouble, so i when with plan B. The old synchronous server was still there.
Now i could serve huge files ( very slowly), but only one at a time. This causes an inconsistent behavior across web browsers. Firefox would load the content after a few retries, chrome based browsers, on the other hand, drop the request after the first connection reset, so the result would be the same, some files simply not downloading.
After a lot of headaches, I embarked on a quest to reduce the file size of all my chunks (No luck there).
So plan D let’s serve the entire site in one huge html file to avoid concurrency problems.1- Disable lazy-loading:
Lazy loading is great for a regular web experience. Allows caching and delivers the UI in the less amount of time possible. Grows more useful as your webapp scales. In this case though, it is a problem since it means that every component that is loaded this way has it’s own js file, this means another request for poor ESP32 WebServer.Documentation is very clear in that regard: https://quasar.dev/quasar-cli/lazy-loading
2- Inline JS and CSS into “index.html”
this is 90% of the website, so is 90% of the problem. For this I used HtmlWebpackPlugin.
Add to your dev dependencies."devDependencies": { ... "html-webpack-plugin": "4.0.0-beta.4", "html-webpack-inline-source-plugin": "1.0.0-beta.2", }
HtmlWebpackPlugin: https://github.com/jantimon/html-webpack-plugin
HtmlWebPackInlineSource: https://github.com/DustinJackson/html-webpack-inline-source-pluginI think this package is discontinued but I couldn’t find any viable alternatives. Normal release version won’t work with quasar, have to use the beta version.
In “quasar.conf.js” include the configuration:extendWebpack(cfg) { … if (ctx.prod) { const HtmlWebpackPlugin = require('html-webpack-plugin'); const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin'); cfg.plugins.push( new HtmlWebpackPlugin({ inlineSource: '.(js|css)$', filename: './bundled/index.html', template: './src/index.bundle.template.html' })); cfg.plugins.push( new HtmlWebpackInlineSourcePlugin(HtmlWebpackPlugin) ); } }
Had to make some small changes in “index.template.html” so I decided to use a separate template without variables.
3 – Don’t use static assets.
The public folder gets copied as-is in build. Webpack doesn’t mess with it. Instead of using static assets use dinamyc assets (in “src/assets”).Docs: https://quasar.dev/quasar-cli/handling-assets
The only thing we have left here are fonts. I’m still figuring that out, but so far this is pretty good compared to my old dashboard built on top of obsolete framesets.