jantimon/html-webpack-plugin

twig syntax with ternary condition = parse error

Closed this issue · 6 comments

Expected behaviour

I'm not using a twig parser because I need it to be executed by the serveur.

So I parse them with .htm extension and I just want htmlwebpackplugin to copy them as the raw src file is.

Current behaviour

This line fail:

<a href="{{ item.url }}" {{ item.viewBag.isExternal ? 'target="_blank"' : '' }}>`
> ERROR in   Error: Parse Error: <a href="{{ item.url }}" {{ item.viewBag.isExternal ? 'target="_blank"' : '' }}>
                  {{ item.title }}
              </a>
          {% else %}
              <span>{{ item.title }}</span>
          {% endif %}
          {% if item.items %}
              <ul>{% partial __SELF__ ~ "::items" items=item.items %}</ul>
          {% endif %}
  {% endfor %}
  
  - htmlparser.js:240 new HTMLParser
    [sng]/[html-minifier]/src/htmlparser.js:240:13
  
  - htmlminifier.js:966 minify
    [sng]/[html-minifier]/src/htmlminifier.js:966:3
  
  - htmlminifier.js:1326 exports.minify
    [sng]/[html-minifier]/src/htmlminifier.js:1326:16
  
  - index.js:316 
    [sng]/[html-webpack-plugin]/index.js:316:18
  
  - task_queues.js:94 processTicksAndRejections
    internal/process/task_queues.js:94:5

I replaced it with an usual condition and it worked:
{% if item.viewBag.isExternal %} 'target="_blank"' {% endif %}

Environment

Node.js v12.14.1
linux 5.0.0-37-generic (Ubuntu 18.04)
npm 6.13.4
└── webpack@4.41.5
└── html-webpack-plugin@3.2.0

Config

Copy the minimal webpack.config.js to produce this issue:
My webpack.config.js is kind of huge, I'm using a personnal tool, the HTMLWebpackPlugin is at the end of the file.

Copy your template file if it is part of this issue:

{% for item in items %}
        {% if item.url %}
            <a href="{{ item.url }}" {{ item.viewBag.isExternal ? 'target="_blank"' : '' }}>
                {{ item.title }}
            </a>
        {% else %}
            <span>{{ item.title }}</span>
        {% endif %}

        {% if item.items %}
            <ul>{% partial __SELF__ ~ "::items" items=item.items %}</ul>
        {% endif %}
{% endfor %}

Relevant Links

I created a repo so you can try by yourself

Can you try to use the https://github.com/webpack-contrib/raw-loader ?

E.g.

plugins: [
  new HtmlWebpackPlugin({
    title: 'Custom template',
    template: '!!raw-loader!./index.html'
  })
]

Same issue. I also deactivated my custom loader to be sure it's not the problem (it just parses some twig custom filters to inject dependency):

modules: {
   rules: [
      /* 
      {
          test: /\.(html?|txt)$/i,
          loader: 'theme-filter-loader'
      }
     */
   ]
},
plugins: [
    new HTMLWebpackPlugin({
        filename: to + "/" + HTMLElement.output_filename,
        template: '!!raw-loader!'+HTMLElement.template,
        inject: false,
        minify: true,
        open: true
    })
]

EDIT: something really weird is happening here: even if webpack passes the compilation with the classic condition, all my variables are downcased!
{% if item.viewBag.isExternal %} target="_blank" {% endif %}
becomes:
{% if item.viewbag.isexternal %} target="_blank" {% endif %}
even with raw-loader and custom loader disabled 😯

Oh it is probably the minifcation!

The minifier will parse and manipulate the template result.
This can only work for correct html.

As you have no html but twig it fails.

Can you please try to disable it?

new HTMLWebpackPlugin({
        // ...
        minify: false,
    })

Without minification, it works...

For now I'm ok to do without html minification (which didn't work with my project anyway, but it may be missconfigured). But I still think it shouldn't happend?

The generated code is send to html-minifier-terser - html-minifier-terser will only accept valid html.

You can see how it fails here:

https://runkit.com/embed/i2wu6duagj6z

const htmlMinifierTerser = require("html-minifier-terser").minify

JSON.stringify(htmlMinifierTerser(`<html>
  
  <a href="{{ item.url }}" {{ item.viewBag.isExternal ? 'target="_blank"' : '' }}>
    My Link
  </a>
    
</html>`))
Error: Parse Error: <a href="{{ item.url }}" {{ item.viewBag.isExternal ? ' target="_blank"' : '' }}>
    My Link
  </a>

Unfortunately there is not much what can done about that issue by the html-webpack-plugin.

Oh, didn't know about that little tool :)
I'll disable the cache system for now and will have a deeper look another day. Thanks for the informations.

Since it's not an HTMLWebpackPlugin issue, I close it :)