DEV Community

Cover image for 🎙️We have implemented new features in HMPL to help developers make web apps smaller in size🔥
Anthony Max Subscriber for HMPL.js

Posted on

🎙️We have implemented new features in HMPL to help developers make web apps smaller in size🔥

Today, we have prepared some cool features that can really help developers make web applications much smaller in size. These features themselves qualitatively complement the already good template language with additional and interesting functionality.

They have been in development for several months now and are also quite expandable, making the future much more promising and clear.

⚙️ Automatic body generation for RequestInit

One of the innovations is the generation of the body of the request to the server. This functionality is very convenient when working with forms, because you do not have to manually specify FormData.

import { compile } from "hmpl-js";

const templateFn = compile(
  `<div>
  <table>
    <caption>
      List of products in the store
    </caption>
    <thead>
      <tr>
        <th scope="col">Product name</th>
        <th scope="col">Quantity</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Coca Cola</td>
        <td>10</td>
      </tr>
      <tr>
        <td>Lays</td>
        <td>4</td>
      </tr>
      {
        {
          "src":"/api/products",
          "after":"submit:#form",
          "autoBody":true,
          "indicators": [
            {
              "trigger": "pending",
              "content": "<tr><td>Loading...</td><td>Loading...</td></tr>"
            }
          ]
        }
      }
    </tbody>
  </table>
  <form id="form">
    <div class="form-example">
      <label>Product name: </label>
      <input type="text" name="product" id="product" required /><br/>
      <label>Quantity: </label>
      <input type="number" name="quantity" id="quantity" required />
    </div>
    <div class="form-example">
      <input type="submit" value="Add product" />
    </div>
  </form>
</div>
  `
);
const obj = templateFn({ credentials: "same-origin" });
const wrapper = document.getElementById("wrapper");
wrapper.appendChild(obj.response);
Enter fullscreen mode Exit fullscreen mode

Here, we send a request to add a product to the table. If it weren't for this functionality, we would have to manually set the parameters via new FormData().set(), but this is done automatically.

Also, it would be great if you supported the project with your star! Thanks ❤️!

💎 Star HMPL ★

🔄 Indicators

Indicators are HTML components that are displayed depending on the status of a server request.

{
  {
    "src": "http://localhost:5000/api/test",
    "indicators": [
       {
         "trigger": "pending",
         "content": "<p>Loading...</p>"
       },
       {
         "trigger": "rejected",
         "content": "<p>Error</p><button>reload</button>"
       }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

With their help, you can create custom loaders that will indicate to the user that the server has not yet returned a response.

loading

🔧 Fully tested

The test coverage of the entire application is 100%, so this functionality will work with a minimum number of bugs.

Fully tested

You can view the report with tests on Codecov, and the tests themselves are in the test folder.

👀 Ready to make your web app smaller?

  • Node Package Manager: You can download it via npm using the command npm i hmpl-js

  • Content Delivery Network: You can include a file with a dependency via CDN using the following code:

<script src="https://unpkg.com/json5/dist/index.js"></script>
<script src="https://unpkg.com/hmpl-js/dist/hmpl.min.js"></script>
Enter fullscreen mode Exit fullscreen mode
  • Locally: Or, there is a similar option with the second one, just download the file to your local machine.

  • Starter project: There is also a starter project that can be deployed via the command npx degit hmpl-language/hello-hmpl-starter my-project

💬 Feedback

You can write your thoughts about the new features in the comments, it will be interesting to read! Or, there is a thematic discord channel for questions and suggestions, there I or someone else will try to answer!

✅ This project is Open Source

So you can take part in it too! This also means you can use it for commercial purposes:

Repo: https://github.com/hmpl-language/hmpl
Website: https://hmpl-lang.dev

Thank you for reading!

Thanks!

Top comments (11)

Collapse
 
deathcrafter profile image
Shaktijeet Sahoo

So, what stops us from using rendering engines and how does this decrease the size of the website?

If you mean the size of files in an app, then you are probably targeting a niche group of developers who care about saving megabytes of space in their storages.

If you mean the bundle size of the app, then your library will also take up space in the bundle, vanilla HTML/CSS/JS will get you the smallest bundle size, that is, using template engines.

Also, with your current example, how are you planning to add a delete button to the table? I am sure you can send an html button with some JS in it, but how will that re-fetch the table element, since you have no idea what is going to be returned from the server.

Again. consider the scenario of multiple people working on an app. The backend dev changes one thing and the whole frontend is wrecked. Now let's say someone wants to do some changes, then he has to make changes to different files in multiple directories, which share component logic. For example, to change your table columns, you have to change the HMPL template, the html file in the backend and the API logic. I am aware that you can send the headers from the API, I just gave an example.

Then comes the King of the board, have you considered how open you are to XSS attacks? You are not sanitizing the responses (I dived a little bit into your code), so anything that is injected as the response is what the user sees. Now, it can also be done with direct html renders, but your method of receiving an html node makes it easier for attacks.

Something new is always welcome but consider if the overhead is worth it.

Collapse
 
anthonymax profile image
Anthony Max

Thank you very much for the detailed comment about the module! What you wrote about XSS attacks is very important. I think I should cover this topic in more detail in the future and audit the module code. The code is based on this, but it only removes the script tag:

fetch('page.html')
  .then(response => {
    return response.text()
  })
  .then(html => {
    const parser = new DOMParser()

    const doc = parser.parseFromString(html, "text/html")

   const docArticle = doc.querySelector('article').appendChild(doc);
  })
  .catch(error => {
     console.error('Failed to fetch page: ', error)
  })
Enter fullscreen mode Exit fullscreen mode

If we are talking about XSS attacks, it is important to understand that this is mainly not the fault of the module, but of the developer, who uses an API that is not under his control, or allows entering HTML code that will later come from the API. If we were talking about PHP, where there is esc_html, then I would understand, but here we need to think about it. This is a very delicate topic, because we need to carefully introduce XSS escaping where it is needed and where it is not needed.

Collapse
 
anthonymax profile image
Anthony Max

Regarding the rest of what you wrote. What you describe in the problem is not a module problem, but the peculiarities of server-oriented methods (SSR, SSG, etc.). I have written 100 times in articles about how a module reduces the bundle size, but I can repeat that, unlike many frameworks and libraries with a bunch of boilerplate, you put it all on the server, and on the client you have an empty framework, where the code is then loaded. Accordingly, the user will load such a framework much faster than a boilerplate from a framework, simply because the size of the final bundle will not be 200 MB, but 10 MB of empty tags with request objects.

Collapse
 
anthonymax profile image
Anthony Max

I added the task to the roadmap, I will conduct a full code audit again and as a result I will tell everyone in detail about everything in the article. Security is a very important topic, so I understand that this is now of primary importance. Thank you very much for the comment!

roadmap

Collapse
 
david_bussell14 profile image
David Bussell

Great article!

Collapse
 
anthonymax profile image
Anthony Max

Thanks!

Collapse
 
c_k_c6c7156c1f991203855d0 profile image
C K

How might you pass headers or POST to an API? It seems like HTMX would still save you, a more coding and be smaller while having a lot more features.

Collapse
 
anthonymax profile image
Anthony Max

hmpl-lang.dev/request.html#method - request methods. Regarding htmx, if it had XMLHTTPRequest standard under the hood, it would send a non-customized request, where, in fact, there is a minimum of settings, and also completely depend on DOM, without having a normal ability to manipulate the HTML that came from the server.

Collapse
 
virender_f3570b6a9356b37d profile image
Virender

Wow 😲 cool I m excited to use this 🙌

Collapse
 
anthonymax profile image
Anthony Max

Thank you! I hope the module will help you

Collapse
 
anthonymax profile image
Anthony Max

And also, a lot of interesting things are being prepared!
roadmap