How to retrieve the nameCache from minify-html minifyJs (UglifyJS / Terser) after a Gulp task stream pipeline

Viewed 138

I am using the Terser fork of UglifyJS inside the Gulp wrapper of html-minify and want to persist and restore the minifyJS nameCache.

The underlying Terser library explains how to do it here but that approach is when you run the library directly. I am running it via the HTML-Minifier embedded "minifyJS" option, and as a gulp task in a stream, so initially I had some trouble with the timing of accessing the options object which the library modifies.

I kind of got it working a gulp task, but the resulting name cache is almost empty. The library is adding in the meta structure (so it seems to be almost working and configured correctly), but there is no content added, i.e. no names.

All I did was add the example in an on finish stream event at the end of the pipeline.

const htmlmin = require('gulp-html-minifier-terser'); 

function myTask(){
  let options = {
    ...
    minifyJS: {
        nameCache: {},
    },
  };
  return gulp.src(path1))
  .pipe(htmlmin(options))
  .pipe(gulp.dest(path2)))
  .on('finish', () => {
    fs.writeFileSync(cacheFileName, JSON.stringify(options.minifyJS.nameCache), "utf8");
  });
}

The problem is the output is only:

{"vars":{"props":{}}}

It has processed dozens of files so I'd expect hundreds of variable names.

The reason I am wanting to persist and restore nameCache in the first place is because I have found when running a minification build (of view templates in an Express app) inside a watch task, each time it is triggered by some file change and runs the build, it uses different variable names which create unnecessary commits in Git. I guess there could be other solutions, like not committing the minified templates to Git, until release or into another repo. But I don't want the extra burden of having to figure out which files are "real" changes or having to commit dozens of files unnecessarily. So if there's another solution to that I don't really need to get the name cache persisted - it just seemed like the direct solution to the random variable names.

UPDATE

The nameCache properties are output when the mangle.properties: true option is set. However this additionally mangles object properties in ways that break the code, so I can't enable this.

Anyway this proves that the on finish approach is right, as I was wondering if there was some timing issue with the pipeline, like I was accessing the nameCache before the library had copied the internal cache back across.

So it seems it's just the function and variable names that are not emerging from the nameCache. (I tried debugging into the library but the compiled Terser library was confusing to step through via the source-map.)

If I add this to the config:

  let options = {
    ...
    minifyJS: {
        nameCache: {},
        mangle: {
            properties: false,
        }
    },
  };

This results in a file like:

{"vars":{"props":{}},"props":{"props":{"$serverSide":"t","$processing":"i", 
 "$ajax":"u","$projectId":"l", ... }}}

I'm not sure why there are three props, but I haven't seen a working example of this cache format so don't know if thats normal. I can see there are no other "vars".

0 Answers
Related