developit / htm

Hyperscript Tagged Markup: JSX alternative using standard tagged templates, with compiler support.
Apache License 2.0
8.71k stars 170 forks source link

An exception occurred when parsing an unclosed label using htm, but no error was reported.This leads to the wrong virtual dom object #122

Open masx200 opened 5 years ago

masx200 commented 5 years ago

An exception occurred when parsing an unclosed label using htm, but no error was reported.

This leads to the wrong virtual dom object.

An exception occurred when parsing an unclosed label with "htm", but no error was reported.

This resulted in the wrong "virtual dom" object.

(async () => {
    function h(type, props, ...children) {
        return {
            type,
            props,
            children
        };
    }
    const {default: htm} = await import('https://unpkg.com/htm?module');
    const html = htm.bind(h);
    return html;
})().then(html => {
    return html`
    <head>
      <meta charset="utf-8" >
      <meta name="viewport" content="width=device-width,initial-scale=1" >
      <meta name="theme-color" content="#ffffff" >
      <title>masx200的github主页-首页</title>
      <!--[if IE]>
        <script src="https://cdn.bootcss.com/babel-polyfill/7.4.4/polyfill.min.js"></script>
      <![endif]-->
      <script
        nomodule=""
        src="https://cdn.jsdelivr.net/gh/masx200/webpack-react-vue-spa-awesome-config@2.4.0/lib/polyfill.min.js"
      ></script>
      <link
        href="https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/main.b9c7ffd191cff11a9b96.css"
        rel="stylesheet"
      >
      <script
        charset="utf-8"
        src="https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.6.c2cea2c684fac63ffae0.js"
      ></script>
      <script
        charset="utf-8"
        src="https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.22.ca40a5fe169fbc33ccf0.js"
      ></script>
      <script
        charset="utf-8"
        src="https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.0.1284ce7c8750a8cfed29.js"
      ></script>
      <script
        charset="utf-8"
        src="https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.13.9d669a3554ec48651e33.js"
      ></script>
      <script
        charset="utf-8"
        src="https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.14.64cca74158382392b422.js"
      ></script>
    </head>
  `;
}).then(temp1 => {
    console.log(JSON.stringify(temp1, null, 4));
});

The 'meta' and 'link' tags above are not closed

The 'meta' and 'link' tags above are not closed

An exception occurred !

[
    "meta",
    {
        "name": "theme-color",
        "content": "#ffffff"
    },
    {
        "type": "title",
        "props": null,
        "children": [
            "masx200的github主页-首页"
        ]
    },
    {
        "type": "script",
        "props": {
            "nomodule": "",
            "src": "https://cdn.jsdelivr.net/gh/masx200/webpack-react-vue-spa-awesome-config@2.4.0/lib/polyfill.min.js"
        },
        "children": []
    },
    {
        "type": "link",
        "props": {
            "href": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/main.b9c7ffd191cff11a9b96.css",
            "rel": "stylesheet"
        },
        "children": [
            {
                "type": "script",
                "props": {
                    "charset": "utf-8",
                    "src": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.6.c2cea2c684fac63ffae0.js"
                },
                "children": []
            },
            {
                "type": "script",
                "props": {
                    "charset": "utf-8",
                    "src": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.22.ca40a5fe169fbc33ccf0.js"
                },
                "children": []
            },
            {
                "type": "script",
                "props": {
                    "charset": "utf-8",
                    "src": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.0.1284ce7c8750a8cfed29.js"
                },
                "children": []
            },
            {
                "type": "script",
                "props": {
                    "charset": "utf-8",
                    "src": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.13.9d669a3554ec48651e33.js"
                },
                "children": []
            },
            {
                "type": "script",
                "props": {
                    "charset": "utf-8",
                    "src": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.14.64cca74158382392b422.js"
                },
                "children": []
            }
        ]
    }
]

The correct output should look like this.

The correct output should look like this.

{
    "type": "head",
    "props": null,
    "children": [
        {
            "type": "meta",
            "props": {
                "charset": "utf-8"
            },
            "children": []
        },
        {
            "type": "meta",
            "props": {
                "name": "viewport",
                "content": "width=device-width,initial-scale=1"
            },
            "children": []
        },
        {
            "type": "meta",
            "props": {
                "name": "theme-color",
                "content": "#ffffff"
            },
            "children": []
        },
        {
            "type": "title",
            "props": null,
            "children": [
                "masx200的github主页-首页"
            ]
        },
        {
            "type": "script",
            "props": {
                "nomodule": "",
                "src": "https://cdn.jsdelivr.net/gh/masx200/webpack-react-vue-spa-awesome-config@2.4.0/lib/polyfill.min.js"
            },
            "children": []
        },
        {
            "type": "link",
            "props": {
                "href": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/main.b9c7ffd191cff11a9b96.css",
                "rel": "stylesheet"
            },
            "children": []
        },
        {
            "type": "script",
            "props": {
                "charset": "utf-8",
                "src": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.6.c2cea2c684fac63ffae0.js"
            },
            "children": []
        },
        {
            "type": "script",
            "props": {
                "charset": "utf-8",
                "src": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.22.ca40a5fe169fbc33ccf0.js"
            },
            "children": []
        },
        {
            "type": "script",
            "props": {
                "charset": "utf-8",
                "src": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.0.1284ce7c8750a8cfed29.js"
            },
            "children": []
        },
        {
            "type": "script",
            "props": {
                "charset": "utf-8",
                "src": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.13.9d669a3554ec48651e33.js"
            },
            "children": []
        },
        {
            "type": "script",
            "props": {
                "charset": "utf-8",
                "src": "https://cdn.jsdelivr.net/gh/masx200/masx200.github.io@4.3.3/chunk.14.64cca74158382392b422.js"
            },
            "children": []
        }
    ]
}
dy commented 5 years ago

htm is not html-compatible, it is jsx-compatible. See #91

masx200 commented 5 years ago

In this case, htm you should first throw an error.

dy commented 5 years ago

Yes, that's annoying feature of htm, stumbled upon that myself many times. <input>, <img> etc oftentimes come unclosed, and just copy-pasting html to htm breaks rendering silently.

goranmoomin commented 5 years ago

@masx200 I’m not a contributor, but AFAIK htm doesn’t throw an error on parse errors because htm prioritizes size. (BTW, I don’t think there are lots of Chinese people here, Mandarin text reduces the readability of the text. If you would really like to provide a Chinese translation, please add it at the end of the issue)

developit commented 5 years ago

Correct - developer ergonomic features like parse/tree errors should be implemented in an editor, not in a library paid for at runtime. I'd recommend using the lit-html plugin for VSCode.

In general, HTM 1 was better suited to the use-case described here, since it was built on top of the DOM's own HTML parser. You can find a similar solution for Preact (and likely React) in preact-markup.