7

I am trying to minify an angularjs application using grunt and terser. I first used uglifiy-es but then read that it has some issues. So I tried terser. But the output does not give me minified files.

The gruntfile.js

    module.exports = function(grunt) {
  grunt.initConfig({
      pkg: grunt.file.readJSON('package.json'),
        //grunt task configuration will go here
        ngAnnotate: {
          options: {
              singleQuotes: true
          },
          app: {
              files: {
                  './public/min-safe/js/_config_min.js': ['./controllers/_config.js'],
                  './public/min-safe/js/ctrl_accountingdashboard.js': ['./controllers/ctrl_accountingdashboard.js'], 

              }
          }
      },
      concat: {
        js: { //target
            src: ['./public/min/app.js', './public/min-safe/js/*.js'],
            dest: './public/min/app.js'
        }
    },
    terser: {
      options: {},
      files: {
        './public/min/app.js': ['./public/min/app.js'],
      },
    }
  });

  //load grunt tasks
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-terser');
  grunt.loadNpmTasks('grunt-ng-annotate'); 

  //register grunt default task
  grunt.registerTask('default', ['ngAnnotate', 'concat', 'terser']);

}
Dwigh
  • 441
  • 5
  • 19

3 Answers3

6

I had the same problem. According to the documentation, this should work but it didn't for me. Wrapping the "files" setting in a custom target works for me:

terser: {
  options: {},
  main: {
    files: {
      './public/min/app.js': ['./public/min/app.js'],
    }
  }
}
Tim
  • 1,272
  • 11
  • 28
  • Thanks for posting this. I had to figure out that `main: { files: {'/*output file path name */': ['/*list of input file names*/']}} ` . In any case, would you know where the documentation for this is? `grunt-terser` returns nothing valuable. – Kiran Subbaraman Aug 27 '19 at 16:37
  • 1
    There is not a whole lot of documentation, but I used this page: https://www.npmjs.com/package/grunt-terser – Tim Sep 03 '19 at 08:02
6

To add to @Tim's great answer:
Here is an example that allows to run grunt-terser with path / file wildcard patterns (globbing) – which it does not support out of the box.

Please note the helper properties _src and _dest in the terser config which are not read by grunt-terser itself but by the task terser_all. This task expands the globbing pattern(s) in _src and builds the real config in the files property. When done it runs terser with that updated config.

module.exports = function (grunt) {
    grunt.initConfig({
        terser: {
            dist: {
                options: {
                    compress: {
                        drop_console: true   // remove console.log, console.info, ...
                    }
                },
                files: {
                    // FILLED through terser_all task below!

                    // Examples config:
                    // "dist/example.js": [ "path/to/files/example.js" ]
                    // "dist/example_joined.js": [ "path/to/files/*.js" ]

                },
                // -----
                // HELPER PROPERTIES to build the files prop (see above) in the terser_all task below.
                _src: [
                    "path/to/files/*.js"
                ],
                _dest: "dist/"
            }
        }
    });

    grunt.registerTask('terser_all', function () {
        // work on this target in terser config
        var terser_target_name = "dist";

        // read the terser config
        var terser_config = grunt.config.get('terser') || {};
        var terser_target_config = terser_config[terser_target_name] || {};

        // get the destination dir
        var destDir = terser_target_config._dest;

        // loop through all source files and create an entry in the terser config for each of it
        var files = grunt.file.expand(terser_target_config._src);
        for (const [i, file] of files.entries()) {
            grunt.log.writeln(file);
            // add this file to the terser config as:  dest_file: src_file
            terser_target_config.files[destDir + file] = file;
        }

        // show new config on CLI
        grunt.log.writeflags(terser_target_config);

        // write back config and run task
        grunt.config.set('terser', terser_config);
        grunt.task.run('terser');
    });

    grunt.loadNpmTasks('grunt-terser');

    grunt.registerTask('build', ['terser_all']);
    grunt.registerTask('default', ['build']);
};
Jpsy
  • 20,077
  • 7
  • 118
  • 115
0

Just a note: If you try to "disable" some options by renaming this disables the whole process. At least this was my result with grunt-terser. I was left with the original js file.

{
   mangleX: {
          reserved: [/* ... */]
   }
}
HolgerJeromin
  • 2,201
  • 20
  • 21