Skip to content
This repository has been archived by the owner on Apr 20, 2018. It is now read-only.

collapseWhitespace in htmlmin task makes usemin destroy the html #44

Open
sindresorhus opened this issue Feb 11, 2013 · 13 comments
Open
Assignees
Labels

Comments

@sindresorhus
Copy link
Member

collapseWhitespace: true in the grunt-contrib-htmlmin makes usemin destroy most of the html.

The resulting index.html from generator-webapp becomes:

<script src="scripts/vendor/modernizr.js"></script>
            <p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
        <![endif]--><!-- Google Analytics: change UA-XXXXX-X to be your site's ID. --><script>var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']];
            (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
            g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
            <script src="scripts/plugins.js"></script>
@sleeper
Copy link
Contributor

sleeper commented Feb 11, 2013

Well, now it's compact ;)
Is there a way to have a view on the output from htmlmin (i.e. the output html) ?

@sindresorhus
Copy link
Member Author

Output form htmlmin:

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class=no-js> <!--<![endif]-->
    <head>
        <meta charset=utf-8>
        <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
        <title></title>
        <meta name=description content="">
        <meta name=viewport content="width=device-width">
        <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
        <link rel=stylesheet href="styles/main.css">
        <!-- build:js scripts/vendor/modernizr.js -->
        <script src="components/modernizr/modernizr.js"></script>
        <!-- endbuild -->

    <body>
        <div class=container style=margin-top:50px>
            <div class=hero-unit>
                <h1>'Allo, 'Allo!</h1>
                <p>You now have</p>
                <ul>
                    <li>HTML5 Boilerplate</li>
                    <li>Twitter Bootstrap</li>
                    <li>RequireJS</li>
                </ul>
                <p>installed.</p>
                <h3>Enjoy coding! - Yeoman</h3>
            </div>
        </div>

        <!--[if lt IE 7]>
            <p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
        <![endif]-->

        <!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
        <script>
            var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']];
            (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
            g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
            s.parentNode.insertBefore(g,s)}(document,'script'));
        </script>

        <!-- build:js scripts/plugins.js -->
        <script src="components/sass-bootstrap/js/bootstrap-affix.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-alert.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-dropdown.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-tooltip.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-modal.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-transition.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-button.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-popover.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-typeahead.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-carousel.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-scrollspy.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-collapse.js"></script>
        <script src="components/sass-bootstrap/js/bootstrap-tab.js"></script>
        <!-- endbuild -->

        <!-- build:js scripts/amd-app.js -->
        <script data-main="scripts/main" src="components/requirejs/require.js"></script>
        <!-- endbuild -->

@btford
Copy link

btford commented Feb 25, 2013

Would love for this to be fixed. :)

@artuska
Copy link

artuska commented Apr 15, 2013

The same problem — usemin does not work after the htmlmin, it just ruins all my HTML code completely. So, usemin understands this:

<!-- build:js js/scripts.js -->
    <script src="js/common.js"></script>
    <script src="js/main.js"></script>
<!-- endbuild -->

but not this (after htmlmin processing — same as above, just compressed in one line):

<!-- build:js js/scripts.js --><script src="js/common.js"></script><script src="js/main.js"></script><!-- endbuild -->

@iham
Copy link

iham commented May 4, 2013

I did some kind of a workaround by splitting htmlmin into two targets.
the first will do all the magic except collapseWhitespace to destination 'dist'.
the second will override the html in 'dist'.

    htmlmin: {
      dist: {
        options: {
          removeComments: true,
          // removeCommentsFromCDATA: true,
          // removeCDATASectionsFromCDATA: true,
          // https://github.com/yeoman/grunt-usemin/issues/44
          // collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeAttributeQuotes: true,
          removeRedundantAttributes: true,
          // useShortDoctype: true,
          removeEmptyAttributes: true,
          // removeOptionalTags: true,
          // removeEmptyElements: true,
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>',
          src: '{,*/}*.html',
          dest: '<%= yeoman.dist %>'
        }]
      },
      deploy: {
        options: {
          collapseWhitespace: true
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.dist %>',
          src: '{,*/}*.html',
          dest: '<%= yeoman.dist %>'
        }]
      }
    }

register your build task like

  grunt.registerTask('build', [
    // put all the other tasks you want to use before htmlmin and usemin
    'htmlmin:dist',
    'usemin',
    'htmlmin:deploy'
  ]);

i've used grunt-rev too and it worked well for me ;)

hope this helps.

@robwierzbowski
Copy link

Why not just run all of htmlmin last? It's safest to do any sort of regex manipulation with a well formed document, so it seems like a better idea to perform manipulations and then minify.

I've been running it this way with no issues.

@AdrienGiboire
Copy link

@robwierzbowski Did you try and see it working your way?

@robwierzbowski
Copy link

@rzschech
Copy link

Running htmlmin last as @robwierzbowski suggests works for me.

@mgol
Copy link

mgol commented Jun 25, 2013

Thanks, @iham, your solution works great!

@qcgm1978
Copy link

qcgm1978 commented Nov 8, 2013

@iham thanks a lot, you solve my problem and let me understand more what usemin does.

@fernandoacorreia
Copy link

I confirm @iham's solution worked for me as well. I suggest it is the default for the webapp generator.

IxDay added a commit to RulzUrLife/RulzUrFront that referenced this issue Dec 27, 2013
@stephanebachelier
Copy link
Collaborator

Would be fixed when #244 shipped. But as said by @robwierzbowski it's safest to do html minification last

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests