diff --git a/build.js b/build.js index 3d38dbad8..8bfd4b24d 100755 --- a/build.js +++ b/build.js @@ -258,12 +258,12 @@ * each template file's basename. * * @private - * @param {String} pattern The file path pattern. - * @param {Object} options The options object. + * @param {String} [pattern='/*.jst'] The file path pattern. + * @param {Object} [options=_.templateSettings] The options object. * @returns {String} Returns the compiled source. */ function buildTemplate(pattern, options) { - pattern || (pattern = './*.jst'); + pattern || (pattern = path.join(cwd, '*.jst')); options || (options = _.templateSettings); var directory = path.dirname(pattern); @@ -289,9 +289,9 @@ ); fs.readdirSync(directory).forEach(function(filename) { - var filepath = path.join(directory, filename); + var filePath = path.join(directory, filename); if (pattern.test(filename)) { - var text = fs.readFileSync(filepath, 'utf8'), + var text = fs.readFileSync(filePath, 'utf8'), precompiled = getFunctionSource(_.template(text, null, options)), prop = filename.replace(/\..*$/, ''); @@ -809,9 +809,9 @@ /** * Creates a debug and minified build, executing the `callback` for each. - * The `callback` is invoked with 2 arguments; (filepath, source) + * The `callback` is invoked with 2 arguments; (filePath, source) * - * @param {Array} options The build options array. + * @param {Array} [options=[]] The build options array. * @param {Function} callback The function called per build. */ function build(options, callback) { @@ -1429,7 +1429,8 @@ if (!isDebug) { workingName += '.min'; minify(source, { - 'silent': isSilent, + 'isSilent': isSilent, + 'isTemplate': isTemplate, 'workingName': workingName, 'onComplete': function(source) { // correct overly aggressive Closure Compiler minification @@ -1458,8 +1459,8 @@ } else { // or invoked directly - build(process.argv, function(source, filepath) { - filepath && fs.writeFileSync(filepath, source, 'utf8'); + build(process.argv, function(source, filePath) { + filePath && fs.writeFileSync(filePath, source, 'utf8'); }); } }()); diff --git a/build/minify.js b/build/minify.js index b04571a96..bba7047e9 100755 --- a/build/minify.js +++ b/build/minify.js @@ -9,7 +9,7 @@ spawn = require('child_process').spawn; /** The directory that is the base of the repository */ - var basePath = path.join(__dirname, '../'); + var basePath = fs.realpathSync(path.join(__dirname, '../')); /** The directory where the Closure Compiler is located */ var closurePath = path.join(basePath, 'vendor', 'closure-compiler', 'compiler.jar'); @@ -18,9 +18,9 @@ var distPath = path.join(basePath, 'dist'); /** Load other modules */ - var preprocess = require(path.join(__dirname, 'pre-compile')), - postprocess = require(path.join(__dirname, 'post-compile')), - uglifyJS = require(path.join(basePath, 'vendor', 'uglifyjs', 'uglify-js')); + var preprocess = require('./pre-compile'), + postprocess = require('./post-compile'), + uglifyJS = require('../vendor/uglifyjs/uglify-js'); /** Closure Compiler command-line options */ var closureOptions = [ @@ -50,14 +50,22 @@ options = source; var filePath = options[options.length - 1], dirPath = path.dirname(filePath), - workingName = path.basename(filePath, '.js') + '.min', - outputPath = path.join(dirPath, workingName + '.js'), - isSilent = options.indexOf('-s') > -1 || options.indexOf('--silent') > -1; + isSilent = options.indexOf('-s') > -1 || options.indexOf('--silent') > -1, + isTemplate = options.indexOf('-t') > -1 || options.indexOf('--template') > -1, + workingName = path.basename(filePath, '.js') + '.min'; + workingName = options.reduce(function(result, value, index) { + return /-wn|--working-name/.test(value) + ? options[index + 1] + : result; + }, workingName); + + var outputPath = path.join(dirPath, workingName + '.js'); source = fs.readFileSync(filePath, 'utf8'); + options = { - 'silent': isSilent, - 'workingName': workingName, + 'isSilent': isSilent, + 'isTemplate': isTemplate, 'onComplete': function(source) { fs.writeFileSync(outputPath, source, 'utf8'); } @@ -71,8 +79,8 @@ * * @private * @constructor - * @param {String} source The source to minify. - * @param {Object} options The options object containing `onComplete`, + * @param {String} [source=''] The source to minify. + * @param {Object} [options={}] The options object containing `onComplete`, * `silent`, and `workingName`. */ function Minify(source, options) { @@ -94,11 +102,12 @@ this.compiled = {}; this.hybrid = {}; this.uglified = {}; - this.isSilent = !!options.silent; + this.isSilent = !!options.isSilent; + this.isTemplate = !!options.isTemplate; this.onComplete = options.onComplete || function() {}; this.workingName = options.workingName || 'temp'; - source = preprocess(source); + source = preprocess(source, options); this.source = source; // begin the minification process @@ -117,10 +126,19 @@ * @param {Function} callback The function to call once the process completes. */ function closureCompile(source, message, callback) { + var options = closureOptions.slice(); + + // use simple optimizations when minifying template files + if (this.isTemplate) { + options = options.map(function(value) { + return value.replace(/^(compilation_level)=.+$/, '$1=SIMPLE_OPTIMIZATIONS'); + }); + } + // the standard error stream, standard output stream, and Closure Compiler process var error = '', output = '', - compiler = spawn('java', ['-jar', closurePath].concat(closureOptions)); + compiler = spawn('java', ['-jar', closurePath].concat(options)); // juggle arguments if (typeof message == 'function') { diff --git a/build/post-compile.js b/build/post-compile.js index 37358a6f9..dc40ac2db 100644 --- a/build/post-compile.js +++ b/build/post-compile.js @@ -56,13 +56,16 @@ // expose `postprocess` if (module != require.main) { module.exports = postprocess; - } else { + } + else { // read the Lo-Dash source file from the first argument if the script // was invoked directly (e.g. `node post-compile.js source.js`) and write to // the same file (function() { - var source = fs.readFileSync(process.argv[2], 'utf8'); - fs.writeFileSync(process.argv[2], postprocess(source), 'utf8'); + var filePath = process.argv[2], + source = fs.readFileSync(filePath, 'utf8'); + + fs.writeFileSync(filePath, postprocess(source), 'utf8'); }()); } }()); diff --git a/build/pre-compile.js b/build/pre-compile.js index dfe28763c..d990f0e3f 100644 --- a/build/pre-compile.js +++ b/build/pre-compile.js @@ -246,15 +246,22 @@ * Pre-process a given Lo-Dash `source`, preparing it for minification. * * @param {String} source The source to process. + * @param {Object} [options={}] The options object. * @returns {String} Returns the processed source. */ - function preprocess(source) { - // remove copyright to add later in post-compile.js - source = source.replace(/\/\*![\s\S]+?\*\//, ''); + function preprocess(source, options) { + options || (options = {}); // remove unrecognized JSDoc tags so Closure Compiler won't complain source = source.replace(/@(?:alias|category)\b.*/g, ''); + if (options.isTemplate) { + return source; + } + + // remove copyright to add later in post-compile.js + source = source.replace(/\/\*![\s\S]+?\*\//, ''); + // add brackets to whitelisted properties so Closure Compiler won't mung them // http://code.google.com/closure/compiler/docs/api-tutorial3.html#export source = source.replace(RegExp('\\.(' + propWhitelist.join('|') + ')\\b', 'g'), "['$1']"); @@ -439,8 +446,12 @@ // was invoked directly (e.g. `node pre-compile.js source.js`) and write to // the same file (function() { - var source = fs.readFileSync(process.argv[2], 'utf8'); - fs.writeFileSync(process.argv[2], preprocess(source), 'utf8'); + var options = process.argv, + filePath = options[options.length - 1], + isTemplate = options.indexOf('-t') > -1 || options.indexOf('--template') > -1, + source = fs.readFileSync(filePath, 'utf8'); + + fs.writeFileSync(filePath, preprocess(source, { 'isTemplate': isTemplate }), 'utf8'); }()); } }()); diff --git a/test/template/a.jst b/test/template/a.jst new file mode 100644 index 000000000..a2a8b6e00 --- /dev/null +++ b/test/template/a.jst @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/test/template/b.jst b/test/template/b.jst new file mode 100644 index 000000000..cad081d19 --- /dev/null +++ b/test/template/b.jst @@ -0,0 +1 @@ +<% print("Hello " + epithet); %>. \ No newline at end of file diff --git a/test/template/c.tpl b/test/template/c.tpl new file mode 100644 index 000000000..c7a43bc1f --- /dev/null +++ b/test/template/c.tpl @@ -0,0 +1 @@ +Hello {{ name }}! \ No newline at end of file