skip to Main Content

I have a small node app using webpack and babel to render the production JS.
In the source JS I have some HTML literals like this e. g.:

breadcrumbsElement.innerHTML = `
        <ul class="breadcrumb mr-breadcrumb">
            <li class="breadcrumb-item">
                <a href="/">HostShop</a>
            </li>
            ${breadcrumbLabel ? `
            <li class="breadcrumb-item">
                <span>${breadcrumbLabel}</span>
            </li>` : ''}
        </ul>
    `;

However when I run build it renders as:

r.innerHTML = `ntt<ul class="breadcrumb mr-breadcrumb">nttt<li class="breadcrumb-item">ntttt<a href="/">HostShop</a>nttt</li>nttt${t ? `nttt<li class="breadcrumb-item">ntttt<span>${t}</span>nttt</li>` : ""}ntt</ul>nt`;

The useless whitespaces are encoded and preserved for some reason.

I tried few popular tools such as terser, babel but without luck.

What’s the best approach to minify this?

2

Answers


  1. The tools you are mentionning are there to minify javascript code, not your data. They won’t interpret your literals and decide for you what is relevant or not.

    If you don’t want these spaces, do not add them in the first place.

    /**
     * Create an HTML element
     * @param {string} tagName - The tag name of the element
     * @param {Record<string, string>} attributes - The attributes of the element
     * @param {string} children - The children of the element
     * @returns {string} The HTML string of the element
     */
    const createElement = (tagName, attributes, children) =>
        `<${tagName}${
            attributes != null
                ? Object.entries(attributes)
                      .map(([key, value]) => ` ${key === 'className' ? 'class' : key}="${value}"`)
                      .join('')
                : ''
        }${children != null && children.length > 0 ? `>${children.filter(Boolean).join('')}</${tagName}>` : ''}`;
    
    breadcrumElement.innerHTML = createElement('ul', { className: 'breadcrumb mr-breadcrumb' }, [
        createElement('li', { className: 'breadcrumb-item' }, [
            createElement('a', { href: '/' }, ['HostShop']),
            breadcrumbLabel ? createElement('span', { className: 'breadcrumb-item' }, [breadcrumbLabel]) : null,
        ]),
    ]);
    

    You will have one more function in your code but your minified code will be smaller.

    You also will have to rewrite you literals but your code will be easier to manage.

    Some tools could help for that.

    But at this point why not just use React/jsx?

    Login or Signup to reply.
  2. It is better to avoid nesting the literals, chaining is better and way more easier to read.

    There is chances that it is also faster to parse.

    In this case the ternary is wrapped into parenthesis, so the chaining is not broken.

    breadcrumbLabel = `I 
    Am<br>
    Multiline :)
    `
    
    breadcrumbsElement.innerHTML = `
            <ul class="breadcrumb mr-breadcrumb">
                <li class="breadcrumb-item">
                    <a href="/">HostShop</a>
                </li>` +
                (breadcrumbLabel ? `
                <li class="breadcrumb-item">
                    <span>${breadcrumbLabel}</span>
                </li>` : '') + '</ul>';
    <div id=breadcrumbsElement>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search