Search code examples
javascriptsassgulpminifygulp-html-replace

Gulp JS and SASS minify tasks that hash the filename and replaces the href and src in index.html


Below is the js minify task:

gulp.task('jsBuildDev', function () {
    return gulp.src(['js/build/*.js'])
        .pipe(concat('build.js'))
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(hash())
        .pipe(uglify())
        .pipe(rename(function (path) { path.basename += "-min" }))
        .pipe(sourcemaps.write('./'))        
        .pipe(gulp.dest('./js/'))
});

Below is the sass minify task:

gulp.task('sass', function () {
    return gulp
        .src('./scss/style.scss')
        .pipe(hash())
        .pipe(sourcemaps.init())
        .pipe(sass(sassOptions).on('error', sass.logError))
        .pipe(sourcemaps.write('./'))
        .pipe(autoprefixer(autoprefixerOptions))
        .pipe(rename(function (path) { path.basename += "-min" }))
        .pipe(gulp.dest('./css/'));
});

Here is a task which replaces out the html that's needed:

gulp.task('htmlreplace', function () {
    gulp.src('pre-built-index.html')
    .pipe(htmlreplace({
        'css': 'styles.min.css',
        'js': 'js/build.min.js'
    }))
    .pipe(rename('index.html'))
    .pipe(gulp.dest('./'));
});

All three tasks work fine but, how do I merge the htmlreplace into the jsBuildDev task; so that the 'js': 'js/build.min.js' is equal to the hashed name found in the js minify task? So it looks like'js': 'js/build-86fb603a0875705077f6491fee6b5e07-min' instead of 'js': 'js/build.min.js'.

The same applies for the sass task but I assume both with be resolved with the same solution.


Solution

  • I'm sure there are more elegant ways to do this but the following works:

    var gulp  =  require('gulp');
    var hash = require('gulp-hash');
    var rename = require('gulp-rename');
    var htmlreplace  =  require('gulp-html-replace');
    
    var hashedJS;
    var hashedCSS;
    
    gulp.task('jsBuildDev',  function ()  {
    
      return gulp.src('./app.js')
       .pipe(hash())
       .pipe(rename(function (path) {
        path.basename += "-min";
    
        hashedJS = path.basename + '.js';
        console.log("hashedJS = " + hashedJS);
        }))
      .pipe(gulp.dest('./js'));
    });
    
    gulp.task('sass', function () {
      return gulp.src('./app.scss')
        .pipe(hash())
        // .pipe(sourcemaps.init())
        // .pipe(sass(sassOptions).on('error', sass.logError))
        // .pipe(sourcemaps.write('./'))
        // .pipe(autoprefixer(autoprefixerOptions))
        .pipe(rename(function (path) {
          path.basename += "-min";
    
          hashedCSS = path.basename + '.css';
          console.log("hashedCSS = " + hashedCSS);
         }))
        .pipe(gulp.dest('./css'));
    });
    
    gulp.task('htmlreplace', ['jsBuildDev', 'sass'], function () {
      return gulp.src('app.html')
      .pipe(htmlreplace({
        'css': hashedCSS,
        'js': hashedJS
       }))
      .pipe(rename('index.html'))
      .pipe(gulp.dest('./'));
    });
    

    It creates a couple of variables that are assigned in the dependent tasks that handle js and scss processing. You run the whole thing with "gulp htmlreplace". All three tasks must be run together for the variables to work.

    Otherwise, you could set the replacement hashed filenames by retrieving their filenames after they are created. By looking in their folders at the most recently created file for example. But what I have done seems easier though not especially elegant.

    Let me know if this works for you.