asyncLiz / rollup-plugin-minify-html-literals

Rollup plugin to minify HTML template literal strings
MIT License
65 stars 9 forks source link

shouldMinify must be explicitely specified if root tag is not HTML #20

Open lxg opened 3 years ago

lxg commented 3 years ago

When running the plugin on template literals which don’t have a wrapping <html> tag, the minification does not work unless the tags in question are explicitely allowed through a custom shouldMinify callback.

The sample code to reproduce this (irrelevant stuff removed):

class MyDemo extends HTMLElement
{
    connectedCallback() {
        this.shadow.innerHTML = `
            <style>
                .content {
                    all: initial;
                    display: block;
                    border: 1px dotted #aaa;
                    padding: 10px;
                }

                h1 {
                    margin: 0;
                }

                ul {
                    overflow: hidden;
                    list-style: none;
                    margin: 15px 0;
                    padding: 0;
                }

                li {
                    float: left;
                    background: #f1f1f1;
                    margin: 0 15px 0 0;
                    padding: 3px 10px;
                }

                .img {
                    background: #f3f3f3;
                    padding: 7px;
                    display: inline-block;
                }

                .img p {
                    margin: 3px 0 0;
                }

                img {
                    min-height: 400px;
                    max-height: 600px;
                    width: 100%;
                }
            </style>

            <div class="content">
                <h1>${this.data.name}</h1>
                <ul>${this.data.labels.map(label => `<li title="${label.desc}">${label.title}</li>`).join('')}</ul>
                <div class="img">
                    <img src="${this.data.images[0].url}">
                    <p>${this.data.images[0].title}</p>
                </div>
                <p>${this.data.description}</p>
            </div>
        `
    }
}

customElements.define('my-demo', MyDemo)

The template literal does not get minified unless I pass an option like:

shouldMinify(template) {
    return (template.parts.some(part => {
            return (
                part.text.includes('<style') ||
                part.text.includes('<div')
            )
        })
    )
}

I’m not sure this is intentional or not; to me it feels like a shortcoming, because it does not support the very common use case of custom elements with Shadow DOM.

At least it might make sense to add an option to the plugin that allows to minify the string even if it’s just a fragment rather than a complete document.