Permalink
Browse files

added preserveComments option, updated docs, moved to uglify-js prope…

…r, added tests (multifile and comments)
  • Loading branch information...
1 parent a2c2ce2 commit 695347b181b3e93e1abb319efc96c7b98ff6bc8f @jsoverson jsoverson committed Nov 24, 2012
View
@@ -0,0 +1 @@
+Please see the [Contributing to grunt](http://gruntjs.com/contributing) guide for information on contributing to this project.
View
@@ -39,14 +39,6 @@ module.exports = function(grunt) {
mangle : false
}
},
- compressed_mangled_sourcemap: {
- files: {
- '/dev/null': ['test/fixtures/lodash.js']
- },
- options : {
- source_map : 'tmp/lodash-c-m-oDEVNULL--source-map.js'
- }
- },
compressed_mangled_DEFAULT: {
files: {
'tmp/lodash-c-m.js': ['test/fixtures/lodash.js']
@@ -72,6 +64,30 @@ module.exports = function(grunt) {
mangle : {},
beautify : {}
}
+ },
+ multifile_out: {
+ files: {
+ 'tmp/jquery-lodash-c-m.js': ['test/fixtures/*.js','!test/fixtures/_*']
+ },
+ options : {
+ mangle : false
+ }
+ },
+ preserveComments_some : {
+ src : 'test/fixtures/_comments.js',
+ dest : 'tmp/comments.js',
+ options : {
+ mangle : false,
+ preserveComments : 'some'
+ }
+ },
+ compressed_mangled_sourcemap: {
+ files: {
+ '/dev/null': ['test/fixtures/lodash.js']
+ },
+ options : {
+ source_map : 'tmp/lodash-c-m-oDEVNULL--source-map.js'
+ }
}
},
View
@@ -58,10 +58,22 @@ Default: `false`
Turns on beautification of the generated source code. Any extra options passed are merged with the options sent to `UglifyJS2.OutputStream()`.
#### source_map
-Type: `string`
+Type: `string`, `Object`
Default: `undefined`
-Specify the sourcemap location to output.
+Specify the sourcemap location to output or, as an `Object`, specify the options to pass directly to UglifyJS.SourceMap()
+
+#### preserveComments
+Type: `Boolean`, `string`, `Function`
+Default: `undefined`
+Options: `false`, `true` | `'all'`, `'some'`
+
+Turn on preservation of comments.
+
+-`false` will turn off all comments
+-`'all'` will preserve all comments in code blocks that have not been squashed or dropped
+-`'some'` will preserve all comments that start with a bang (`!`) or a closure compiler style directive (`@preserve`, `@license`, `@cc_on`)
+-`Function` specify your own comment preservation function. You will be passed the current node and the current comment and are expected to return a `true`|`false`
#### banner
Type: `string`
@@ -147,4 +159,4 @@ _(Nothing yet)_
--
Task submitted by <a href="http://benalman.com">"Cowboy" Ben Alman</a>.
-*Generated on Sun Nov 18 2012 07:27:10.*
+*Generated on Fri Nov 23 2012 23:10:05.*
@@ -23,10 +23,22 @@ Default: `false`
Turns on beautification of the generated source code. Any extra options passed are merged with the options sent to `UglifyJS2.OutputStream()`.
## source_map
-Type: `string`
+Type: `string`, `Object`
Default: `undefined`
-Specify the sourcemap location to output.
+Specify the sourcemap location to output or, as an `Object`, specify the options to pass directly to UglifyJS.SourceMap()
+
+## preserveComments
+Type: `Boolean`, `string`, `Function`
+Default: `undefined`
+Options: `false`, `true` | `'all'`, `'some'`
+
+Turn on preservation of comments.
+
+-`false` will turn off all comments
+-`'all'` will preserve all comments in code blocks that have not been squashed or dropped
+-`'some'` will preserve all comments that start with a bang (`!`) or a closure compiler style directive (`@preserve`, `@license`, `@cc_on`)
+-`Function` specify your own comment preservation function. You will be passed the current node and the current comment and are expected to return a `true`|`false`
## banner
Type: `string`
View
@@ -29,7 +29,7 @@
},
"dependencies": {
"gzip-js": "~0.3.1",
- "uglify-js2": "~2.1.10"
+ "uglify-js": "~2.2.1"
},
"devDependencies": {
"grunt-contrib-jshint": "0.1.0",
View
@@ -9,7 +9,7 @@
'use strict';
// External libs.
-var uglifyjs = require('uglify-js2');
+var UglifyJS = require('uglify-js');
var gzip = require('gzip-js');
var fs = require('fs');
@@ -19,62 +19,87 @@ exports.init = function(grunt) {
// Minify with UglifyJS2.
// From https://github.com/mishoo/UglifyJS2
// API docs at http://lisperator.net/uglifyjs/
- exports.minify = function(src, dest, options) {
+ exports.minify = function(files, dest, options) {
options = options || {};
- var code = grunt.file.read(src);
grunt.verbose.write('Minifying with UglifyJS...');
try {
-
- var ast = uglifyjs.parse(code, {
- // filename necessary for source map
- filename : src
- });
+ var topLevel = null,
+ totalCode = '';
+
+ files.forEach(function(file){
+ var code = grunt.file.read(file);
+ totalCode += code;
+ topLevel = UglifyJS.parse(code, {
+ filename : file,
+ toplevel : topLevel
+ })
+ })
var outputOptions = {
beautify : false,
source_map : null
};
+ if (options.preserveComments) {
+ if (options.preserveComments === 'all' || options.preserveComments === true) {
+ // preserve all the comments we can
+ outputOptions.comments = true;
+ } else if (options.preserveComments === 'some') {
+ // preserve comments with directives or that start with a bang (!)
+ outputOptions.comments = function(node, comment) {
+ return /^!|@preserve|@license|@cc_on/i.test(comment.value);
+ }
+ } else if (grunt.util._.isFunction(options.preserveComments)) {
+ // support custom functions passed in
+ outputOptions.comments = options.preserveComments;
+ }
+ }
+
if (options.beautify) {
grunt.util._.extend(outputOptions, options.beautify);
outputOptions.beautify = true;
}
if (options.source_map) {
- outputOptions.source_map = uglifyjs.SourceMap({
- file : dest,
- root: undefined,
- orig: undefined
- });
+ if (grunt.util._.isObject(options.source_map)) {
+ outputOptions.source_map = UglifyJS.SourceMap(options.source_map);
+ } else {
+ outputOptions.source_map = UglifyJS.SourceMap({
+ file : dest,
+ root: undefined,
+ orig: undefined
+ });
+ }
}
- var output = uglifyjs.OutputStream(outputOptions);
+ var output = UglifyJS.OutputStream(outputOptions);
// Need to call this before we mangle or compress,
// and call after any compression or ast altering
- ast.figure_out_scope();
+ topLevel.figure_out_scope();
if (options.compress !== false) {
- var compressor = uglifyjs.Compressor(options.compress);
- ast = ast.transform(compressor);
+ if (options.compress.warnings !== true) options.compress.warnings = false;
+ var compressor = UglifyJS.Compressor(options.compress);
+ topLevel = topLevel.transform(compressor);
// Need to figure out scope again after source being altered
- ast.figure_out_scope();
+ topLevel.figure_out_scope();
}
if (options.mangle !== false ) {
// compute_char_frequency optimizes names for compression
- ast.compute_char_frequency(options.mangle);
+ topLevel.compute_char_frequency(options.mangle);
// Requires previous call to figure_out_scope
// and should always be called after compressor transform
- ast.mangle_names(options.mangle);
+ topLevel.mangle_names(options.mangle);
}
// Print the ast to OutputStream
- ast.print(output);
+ topLevel.print(output);
var min = output.get();
@@ -83,7 +108,7 @@ exports.init = function(grunt) {
}
var result = {
- max : code,
+ max : totalCode,
min : min,
source_map : outputOptions.source_map
};
@@ -93,7 +118,7 @@ exports.init = function(grunt) {
return result;
} catch(e) {
grunt.verbose.error();
- if (e instanceof uglifyjs.DefaultsError) {
+ if (e instanceof UglifyJS.DefaultsError) {
grunt.warn(e.msg);
grunt.verbose.log("Supported options:");
grunt.verbose.debug(e.defs);
View
@@ -17,49 +17,43 @@ module.exports = function(grunt) {
grunt.registerMultiTask('uglify', 'Minify files with UglifyJS.', function() {
// Merge task-specific and/or target-specific options with these defaults.
var options = this.options({
- banner: '',
- uglify: {}
+ banner : '',
+ compress : {
+ warnings : false
+ },
+ mangle : {},
+ beautify : false
});
- // Process banner.
- var banner = grunt.template.process(options.banner);
-
- // Iterate over all specified file groups.
- this.files.forEach(function(fileObj) {
- // The source file to be minified.
- var srcpath = fileObj.src[0];
- var files = grunt.file.expandFiles(srcpath);
- // Abort if source didn't match any files.
- if (files.length === 0) {
- grunt.log.error('Source file "' + srcpath + '" not found.');
- return;
- }
+ // Abort if source didn't match any files.
+ if (this.file.src.length === 0) {
+ grunt.log.error('No source files found.');
+ return;
+ }
- var src = files[0];
+ // Get source of specified file.
+ var result = uglify.minify(this.file.src, this.file.dest, options);
- // Get source of specified file.
- var result = uglify.minify(src, fileObj.dest, options);
-
- // Concat banner + minified source.
- var output = banner + result.min;
+ // Concat banner + minified source.
+ var banner = grunt.template.process(options.banner);
+ var output = banner + result.min;
- // Write the destination file.
- grunt.file.write(fileObj.dest, output);
+ // Write the destination file.
+ grunt.file.write(this.file.dest, output);
- // Write sourcemap
- if (options.source_map) {
- grunt.file.write(options.source_map, result.source_map);
- }
+ // Write sourcemap
+ if (options.source_map) {
+ grunt.file.write(options.source_map, result.source_map);
+ }
- // Print a success message.
- grunt.log.writeln('File "' + fileObj.dest + '" created.');
+ // Print a success message.
+ grunt.log.writeln('File "' + this.file.dest + '" created.');
- // ...and report some size information.
- minlib.info(result.min, result.max);
- }, this);
+ // ...and report some size information.
+ minlib.info(result.min, result.max);
+ }, this);
- // Fail task if any errors were logged.
- if (this.errorCount > 0) { return false; }
- });
+ // Fail task if any errors were logged.
+ if (this.errorCount > 0) { return false; }
};
@@ -0,0 +1,12 @@
+/*!
+ * I am a comment
+ */
+function foo(){return 42}// @preserve preserve
+// @license license
+function bar(){return 2*foo()}/* @preserve
+ * multiline preserve
+ */
+/* @license
+ * multiline license
+ */
+function baz(){return bar()*bar()}
Oops, something went wrong.
@@ -0,0 +1,21 @@
+/*!
+ * I am a comment
+ */
+function foo() {
+ return 42;
+}
+// @preserve preserve
+// @license license
+function bar() {
+ return foo()*2;
+}
+/* @preserve
+ * multiline preserve
+ */
+/* @license
+ * multiline license
+ */
+function baz() {
+ return bar()*bar();
+}
+// end - not preserved
Oops, something went wrong.

0 comments on commit 695347b

Please sign in to comment.