javascriptphphtmlgulpminify

Minify HTML, but don't touch PHP with Gulp


The problem

I have a lot of .php files, mostly containing HTML, but also some PHP lines on top (e.g. form trigger code or similar). So they look like

<?php
if($someValue){
    //doSth
}
//more content
?>
<!DOCTYPE html>
<html lang="de">
<head>
    <title>My Website</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
<!-- Content and scripts here -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</body>
</html>

The goal

My goal is to minify the HTML (and maybe even the inline javascript, but that's just a little extra), without touching the PHP on top. I'm using Gulp as automated build tool and would like to see a solution using this tool and any extra packages as they are needed.


Solution

  • The gulp-htmlmin module uses the html-minifier module, which has plenty of options (displayed on both its npmjs.com and github pages) that can be used. The option we will focus on is ignoreCustomFragments.

    var gulp = require(gulp),
        htmlmin = require(gulp-htmlmin);
    
    gulp.task('htmltask', function(){
      return gulp.src(['./dev/*.html','./dev/*.php'])
          .pipe(htmlmin({
            collapseWhitespace: true,
            ignoreCustomFragments: [ /<%[\s\S]*?%>/, /<\?[=|php]?[\s\S]*?\?>/ ]
          }))
          .pipe(gulp.dest('./site'));
    });
    

    In the above code, you see we are using ignoreCustomFragments with the regex /<\?[=|php]?[\s\S]*?\?>/ to ignore code starting with <? and <?php and ending with ?>.

    By default, html-minifier ignores php, so you don't have to worry about setting ignoreCustomFragments.

    EDIT Thanks amersk

    Some php files you work with may not have closing tags, for example many WordPress files do not. An alternative would be to use the following instead:

    ignoreCustomFragments: [/<\?[\s\S]*?(?:\?>|$)/]