asyncLiz / minify-html-literals

Minify HTML template literal strings
MIT License
68 stars 14 forks source link

Unit is dropped when using template literals in CSS #31

Open Frank3K opened 3 years ago

Frank3K commented 3 years ago

Given the following input:

import { minifyHTMLLiterals } from 'minify-html-literals';

const result = minifyHTMLLiterals(
  `const duration = 2;
   html\`
      <style>
        .selector {
          animation-duration: \${duration}s;
        }
      </style>
    \``,
  {
    fileName: 'render.js'
  }
);

console.log(result.code);

The expected output is:

const duration = 2;
   html`<style>.selector{animation-duration:${duration}s}</style>`

Instead, the unit (s) is dropped in the actual output:

const duration = 2;
   html`<style>.selector{animation-duration:${duration}}</style>`

In comparison, the unit is preserved when there are no template literals inside:

import { minifyHTMLLiterals } from 'minify-html-literals';

const result = minifyHTMLLiterals(
  `html\`
      <style>
        .selector {
          animation-duration: 2s;
        }
      </style>
    \``,
  {
    fileName: 'render.js'
  }
);

console.log(result.code);
WickyNilliams commented 2 years ago

This can also happen with inline style attributes!

Given this input:

function example(width) {
  return html`<div style="--width: ${width}px"></div>`;
}

The output is:

function example(width) {
  return html`<div style="--width:${width}"></div>`;
}

Here's a code sandbox showing the issue https://codesandbox.io/s/minify-html-literals-loses-css-units-40yhjz?file=/src/index.js

WickyNilliams commented 2 years ago

In the above case, a slight tweak to use template literals for the attribute value avoids the issue, and now the output is as expected

Input:

function example(width) {
  return html`<div style=${`--width: ${width}px`}></div>`;
}

Output:

function example(width) {
  return html`<div style="${`--width: ${width}px`}"></div>`;
}