Gzip Sage assets in Gulp task

I’m looking to gzip my assets during the deploy after they have been compiled on the server, for which I already have a task for.

I’m wondering how I might approach having Capistrano to read in the dist/assets.json and then allow me to iterate commands on each of those files? The only resources I have been able to find about this seem to be very Rails-specific.

(Using Bedrock with Sage)

Any help is much appreciated!

Edit
I realized trying reading the assets.json may be over-complicating things.

I tried using this task after my task which runs gulp --production but to no avail. The deploy isn’t failing, but the gzipped files are not being created.

namespace :assets do
  desc 'Compress css|js with gzip'
  task :gzip do
    on roles(:app) do
      within fetch(:release_path).join(theme_relpath) do
        execute 'for file in $(find ./dist -name "*.js"); do gzip $file -f -c > $file.gz; done'
        execute 'for file in $(find ./dist -name "*.css"); do gzip $file -f -c > $file.gz; done'
      end
    end
  end
end

Seems like this should be handled by Gulp. Get https://github.com/jstuckey/gulp-gzip working for the build task.

Then it’s just the normal deploy workflow.

Thanks Scott,

I found that too. When I tried to implement this, it merely compresses the dist asset as a .gz - which is what I want - however I’m looking to create the .gz in addition to the uncompressed file. I’m sure this is possible to do with gulp too, I’m just not familiar enough with it to do that.

Should that be added as a new task, styles task, or to the cssTasks function?

After messing with this for a while, I was able to get the extra file created by adding additional .pipe() s to the writeToManifest() function, but the problem is that it’s writing the compressed .gz filename in the manifest instead of the uncompressed.

That sounds obvious but it was the closest I was able to achieve. Here’s my code:

var writeToManifest = function(directory) {
  return lazypipe()
    .pipe(gulp.dest, path.dist + directory)
    .pipe(function() {
      return $.if('**/*.{js,css}', browserSync.reload({stream:true}));
    })
    .pipe(gzip)
    .pipe(gulp.dest, path.dist + directory)
    .pipe($.rev.manifest, revManifest, {
      base: path.dist,
      merge: true
    })
    .pipe(gulp.dest, path.dist)();
};

It seems like I need to be able to run the gzip pipe and write that file after the uncompressed file is created without interfering with the stream that the manifest uses. Maybe this isn’t the right function to be trying to fit this in, but it made sense to do it at the same time the uncompressed file is written. Ideally, I think the creation of the compressed version would only happen when --production is passed.

Tips/pointers anyone?

Hey @austin :wink:

If someone is still interested in the subject, here is my solution to make static gzip work:

Add gzips to enabled variable:

// CLI options
var enabled = {
  // Enable static gzip when `--production`
  gzips: argv.production
};

Create a gzip gulp task:

// ## Gzips
// Generate static gzip files for server
gulp.task('gzip', function() {
  return gulp.src('./' + path.dist + '**/*.{html,xml,svg,json,css,js,ttf,otf,eot}', { base: './' + path.dist })
        .pipe(gulpif(enabled.gzips, gzip({
            gzipOptions: { level: 9, memLevel: 9 }
          })))
        .pipe(gulp.dest('./' + path.dist));
});

And then call it on build task.

Hope it helps!

5 Likes

@gabrielgiordan,

You sir, are a badass. :muscle:

Works perfectly. Thanks for posting this!

Couldn’t have done it better myself!