cfware / babel-plugin-template-html-minifier

Minify HTML in tagged template strings using html-minifier
MIT License
63 stars 4 forks source link

Build ends with error when `<style>` is included in the html template (lit-element) #56

Closed jarrodek closed 4 years ago

jarrodek commented 4 years ago

I have the following configuration:

...
require.resolve('babel-plugin-template-html-minifier'),
{
  modules: {
    'lit-html': ['html'],
    'lit-element': [
      'html',
      {name: 'css', encapsulation: 'style'}
    ],
  },
  strictCSS: true,
  htmlMinifier: {
    collapseWhitespace: true,
    conservativeCollapse: true,
    removeComments: true,
    caseSensitive: true,
    minifyJS: true,
    minifyCSS: true,
  },
},

Then in the components, for some valid reasons, I am using styles defined as follows:

import { html, css, LitElement } from 'lit-element';
class Element extends LitElement {
  get styles() {
      return css`...`;
   }
   render() {
      return html`<style>${this.styles}</style> ...`;
   }
}

This causes an error like this:

[!] (plugin babel) SyntaxError: /tmp/tmp-35547-nhbZ1VHAVgUn/node_modules/@anypoint-web-components/anypoint-button/src/AnypointIconButton.js: [babel-plugin-template-html-minifier] Could not minify CSS: Invalid character(s) 'babel-plugin-template-html-minifier:c0fruxltjpt ' at 1:1. Ignoring. 35 | 36 | render() { 37 | return html` 40 | <div class="icon"

For now I will disable css minification as then it start working again but it would be nice to have this working.

coreyfarrell commented 4 years ago

Using <style>${this.styles}</style> is not supported and also not needed. See lit-element documentation, you need to make your styles property static get styles() { ... } and it'll just work.

Beyond this if you REALLY must use create the style as you have here then it requires additional effort to prevent attempts to minify the <style>${this.styles}<style> code:

import { html, css, LitElement } from 'lit-element';
class Element extends LitElement {
  get styles() {
      return css`...`;
   }
   render() {
      const htmlNoMin = html;
      const style = htmlNoMin`<style>${this.styles}<style>`;
      return html`${style} ...`;
   }
}
jarrodek commented 4 years ago

Like I said, there's a valid reason for that :) I am aware of the styling API for lit element. Mind that putting a style tag inside a component's shadow root is a valid approach.

Thanks for a possible walk around.

coreyfarrell commented 4 years ago

Yeah the thing is having <style> with dynamic content cannot be supported by the underlying libraries which actually minify. Might be possible to use bindings for certain css values like content: "${content}" but most likely only quoted values.