asyncLiz / minify-html-literals

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

CSS minify doesn't work for shorthand attribute values #19

Open gerriet-hinrichs opened 4 years ago

gerriet-hinrichs commented 4 years ago

Having a placeholder with a semicolon breaks the css if added to shorthand attribute values like border.

Code to reproduce:

const { minifyHTMLLiterals } = require('minify-html-literals');

const source = `
const borderStyle = 'solid';
const styles = css\`
    div {
        /* adding the placeholder here breaks the css */
        border: 1px \${borderStyle} black; 
        margin: 12px;
    }
\`
`;
try {
    // this failes because the minifier drops parts of the broken css
    const result = minifyHTMLLiterals(source, { fileName: 'test.js' });
    console.log(result.code);
} catch (e) {
    console.error(e);
}
gerriet-hinrichs commented 4 years ago

This issue is hard to fix:

A workaround would be to simply use the more specific attributes like so:

const borderStyle = 'solid';
const styles = css`
    div {
        border: 1px none black;
        border-style: ${borderStyle};
    }
`;

I've written a quick test for this issue that you can add to your tests:

  // test for github issue #19
  const CSS_SHORTHAND_SOURCE = `
    const borderStyle = 'solid';
    const styles = css\`
      div {
        border: 1px \${borderStyle} #000;
      }
    \`;
  `;

  const CSS_SHORTHAND_SOURCE_MIN = `
    const borderStyle = 'solid';
    const styles = css\`div{border:1px \${borderStyle} #000}\`;
  `;

  it('should handle templates in shorthand attributes correctly', () => {
    const result = minifyHTMLLiterals(CSS_SHORTHAND_SOURCE, {
      fileName: 'test.js'
    });
    expect(result).to.be.an('object');
    expect(result!.code).to.equal(CSS_SHORTHAND_SOURCE_MIN);
  });