julesbloemen's avatar

Strange problem bootstrap table and browserify .vue components in production

Hello dear developers,

I have a very strange problem, when building with development everything is fine. Building in production makes my bootstrap tables break.

We use Vue components and browserify, the problem only exists in Vue components in production. We use Vue single file components, I think the build process performs a pre-render on the template code with those kind of files... It basically removes the tbody tag :-|

Laravel version:

"laravel/framework": "5.3.*",
"laravelcollective/html": "5.*",

Package.json:

{
  "private": true,
  "scripts": {
    "production": "NODE_ENV=production; gulp --production",
    "dev": "gulp",
    "watch": "gulp watch",
    "watch_nocolors": "gulp watch --no-colors"
  },
  "devDependencies": {
    "bootstrap-sass": "^3.3.7",
    "gulp": "^3.9.1",
    "jquery": "^3.1.0",
    "laravel-elixir": "^6.0.0-14",
    "laravel-elixir-browserify-official": "^0.1.3",
    "laravel-elixir-vue-2": "^0.3.0",
    "laravel-elixir-vueify": "^2.0.0",
    "laravel-elixir-webpack-official": "^1.0.2",
    "lodash": "^4.16.2",
    "yargs": "^8.0.2"
  },
  "browser": {
    "vue": "vue/dist/vue.common"
  },
  "dependencies": {
    "dotenv": "^4.0.0",
    "gulp-install": "^1.1.0",
    "vue": "^2.3.4",
    "vue-moment": "^2.0.2",
    "vue-resource": "^1.3.4",
    "vue-router": "^2.5.3",
    "vue2-dropzone": "^2.3.5"
  }
}

Part of gulpfile.js:

// assignerform contain Vue router / components etc...
mix.browserify('users/assignerform.js');

Correct Bootstrap table development in single file Vue component (HTML copied from browser):

<table class="table">
    <thead>
        <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Username</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">1</th>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
        </tr>
        <tr>
            <th scope="row">2</th>
            <td>Jacob</td>
            <td>Thornton</td>
            <td>@fat</td>
        </tr>
        <tr>
            <th scope="row">3</th>
            <td>Larry</td>
            <td>the Bird</td>
            <td>@twitter</td>
        </tr>
    </tbody>
</table>

Broken Bootstrap table production in single file Vue component (HTML copied from browser):

<table class="table">
    <thead>
        <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Username<tbody>
                    <tr>
                        <th scope="row">1<td>Mark</td>
                            <td>Otto</td>
                            <td>@mdo<tr>
                                    <th scope="row">2<td>Jacob</td>
                                        <td>Thornton</td>
                                        <td>@fat<tr>
                                                <th scope="row">3<td>Larry</td>
                                                    <td>the Bird</td>
                                                    <td>@twitter</td>
                                                </th>
                                            </tr>
                                        </td>
                                    </th>
                                </tr>
                            </td>
                        </th>
                    </tr>
                </tbody>
            </th>
        </tr>
    </thead>
</table>

The Vue single file component template is very simple...

<template xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
    <div class="page-inner" id="timecard">
        <div class="page-title" style="background-color:skyblue">
            <h3>Mijn uren</h3>
        </div>
        <div id="main-wrapper">

            <table class="table">
                <thead>
                <tr>
                    <th>#</th>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Username</th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    <th scope="row">1</th>
                    <td>Mark</td>
                    <td>Otto</td>
                    <td>@mdo</td>
                </tr>
                <tr>
                    <th scope="row">2</th>
                    <td>Jacob</td>
                    <td>Thornton</td>
                    <td>@fat</td>
                </tr>
                <tr>
                    <th scope="row">3</th>
                    <td>Larry</td>
                    <td>the Bird</td>
                    <td>@twitter</td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>

</template>

<script>
</script>

Thanks a lot for any directions on this...

0 likes
7 replies
sutherland's avatar

What does the source for your component template look like?

julesbloemen's avatar

Edited original post, added .vue single file component used.

sutherland's avatar

I know Vue sometimes uses the scope prop, what happens if you try removing that attribute?

julesbloemen's avatar

Good shot, but same problem.

<table class="table">
    <thead>
        <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Username<tbody>
                    <tr>
                        <th>1<td>Mark</td>
                            <td>Otto</td>
                            <td>@mdo<tr>
                                    <th>2<td>Jacob</td>
                                        <td>Thornton</td>
                                        <td>@fat<tr>
                                                <th>3<td>Larry</td>
                                                    <td>the Bird</td>
                                                    <td>@twitter</td>
                                                </th>
                                            </tr>
                                        </td>
                                    </th>
                                </tr>
                            </td>
                        </th>
                    </tr>
                </tbody>
            </th>
        </tr>
    </thead>
</table>
sutherland's avatar

Hmm, maybe it's that thead and tbody are on the same indentation level? Really doubt it's that but otherwise I'm lost too.

julesbloemen's avatar
julesbloemen
OP
Best Answer
Level 2

Ok finally figured it out. The lib html-minifier used by vueify has the option to removeOptionalTags, this option breaks a standard bootstrap table :-( tested it with the newest version of html-minifier which was 3.5.5.

having a vue.config.js in your project root with the following overwrite solved my issue:

module.exports = {
    htmlMinifier: {
        removeOptionalTags: false,
    },
}
1 like

Please or to participate in this conversation.