Parcel: 馃悰Vue self-closing tags broken on build but fine on dev

Created on 30 Mar 2018  路  14Comments  路  Source: parcel-bundler/parcel

When a div is self-closed in vue template, it will not correctly closed causing things below get embed in that self-closing tag.

| Code | Result |
|------|--------|
| image | image |

And strangely it's a production-build-only (parcel build) bug. Works fine on dev.

馃帥 Configuration (.babelrc, package.json, cli command)

Included in repro.

馃拋 Possible Solution

No idea, even don't know it's a Vue issue or a Parcel issue.

馃敠 Context

馃捇 Code Sample

https://github.com/laosb/parcel-vue-test/commit/60baa3f7e1de3b963a5af1aeddba10d5e24a49a6

馃實 Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.7.0 |
| Node | 9.8.0 |
| npm/Yarn | Yarn 1.5.1 |
| Operating System | macOS 10.13.3 |

Bug

Most helpful comment

@andrewbanchich Can you try config {"recognizeSelfClosing": true} in .posthtmlrc ?

All 14 comments

After seeking the issue i found in HTMLAsset.parse, posthtml-parser doesn't make the div closed.

20180330230835

I found this: https://github.com/posthtml/posthtml-parser/issues/23

maybe we need a option passing into parse()

Self-closing tags are working for me on 1.7, however I'm seeing the same issue. I believe the problem is the two div children in the parent div. For example, if I have:

<template>
    <div>
      <div>A</div>
      <div>B</div>
    </div>
</template>

<script>
  import axios from 'axios'

  export default {
    data(){return {}},
    created(){
      console.log(axios)
    }
  }
</script>

then axios will be undefined when using "build" but be fine when in dev mode.

However,

<template>
    <div>
      <div>A</div>
    </div>
</template>

<script>
  import axios from 'axios'

  export default {
    data(){return {}},
    created(){
      console.log(axios)
    }
  }
</script>

and

<template>
    <div>
      <div><span/></div>
    </div>
</template>

<script>
  import axios from 'axios'

  export default {
    data(){return {}},
    created(){
      console.log(axios)
    }
  }
</script>

Both work correctly. See if the self closing tag works by itself in your div without the sibling. Mind you, this is still a bug.

I am not sure if this is the same issue, but I'm getting an "invalid attribute name" when running parcel build but not when running parcel index.html. It says it's invalid because it starts with @, which I assume is the Vue shorthand syntax (e.g. @click).

I can't be sure, though, since the error doesn't tell me which file or compinent it is coming from.

@andrewbanchich this is a individual issue, same goes for #1089 it would be great if you can open up a issue that contains your markup 馃槉

Any progress? This blocks us from switching to Parcel.

It鈥檚 reasonable for parcel to use xml mode in parsing vue files, since it is not really valid html at all (though vue claims it can be, for embedding templates in html). Most vue linters requires self-closing when no content presented in the element.

I've investigate your issue since mine is resolved. posthtml does not parse the html correctly to the ast. And posthtml is only called if your markup is dirty (mixed html5 and xml) or you minify it, which happens on production build.

This is a simple example to test the issue in a isolated enviroment.

var posthtml = require('posthtml');
var htmlnano = require('htmlnano');

var html = '<div><div class="test-self-close" /><div>inside</div></div>'
var options = {closingSingleTag: 'slash'}

posthtml().process(html, options).then(function (result) {
    console.log(result.html)
    console.log(JSON.stringify(result.tree, null, 2))
}).catch(function (error) { return console.log(error) })

@laosb you can avoid this issue for now by configuration parcel via the API https://parceljs.org/api.html just make sure to run the script with with the correct enviroment variables

eg: process.env.NODE_ENV === 'production'

const Bundler = require('parcel-bundler');
const Path = require('path');

const file = Path.join(__dirname, './index.html');

const options = {
  // prevents posthtml from being called as long as the markup is not dirty
  minify: false,
};

const bundler = new Bundler(file, options);

bundler.bundle();

What about creating a .posthtmlrc or .htmlnanorc config to workaround this for now?

@DeMoorJasper tried all possible configurations, the issue is how posthtml seperates selfclosing tags. For example the option closingSingleTag only affects elements from the singleTags option but then all it outputs is a single div.

You can test that via the option variable. eg: {singleTags: ['div'], closingSingleTag: 'slash'}

Any updates on this? Ran into this in production today and it kind of sucks.

@K900 we probably need to await this PR https://github.com/posthtml/posthtml-parser/pull/21, but it is really outdated by now. Maybe we could create a issue to increase the importance. I'll do it later today.

Not sure why this was closed. This is still happening for me and completely broke my site build.
Shouldn't this be pretty high on the radar of bugs to fix? Parcel is unusable for anyone using SVGs because it can't handle the uppercase b in "viewBox" and it can't handle self-closing tags. Everything looks perfect in dev but after build SVGs are huge and the whole site is broken because of self-closing tags.

@andrewbanchich Can you try config {"recognizeSelfClosing": true} in .posthtmlrc ?

@luikore That worked! Thank you!!!

How did you find that setting documentation?

Was this page helpful?
0 / 5 - 0 ratings