mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-08 18:17:48 +00:00
lodash: Cleanup build.js. [jddalton]
Former-commit-id: 4d044d708e78e8d0f8e869319f4c2c27cfa5e5f6
This commit is contained in:
234
build.js
234
build.js
@@ -10,19 +10,36 @@
|
|||||||
/** The build directory containing the build scripts */
|
/** The build directory containing the build scripts */
|
||||||
var buildPath = path.join(__dirname, 'build');
|
var buildPath = path.join(__dirname, 'build');
|
||||||
|
|
||||||
|
/** The directory where the Closure Compiler is located */
|
||||||
|
var closurePath = path.join(__dirname, 'vendor', 'closure-compiler', 'compiler.jar');
|
||||||
|
|
||||||
/** The distribution directory */
|
/** The distribution directory */
|
||||||
var distPath = path.join(__dirname, 'dist');
|
var distPath = path.join(__dirname, 'dist');
|
||||||
|
|
||||||
/** Load the pre- and post-processors */
|
/** Load other modules */
|
||||||
var preprocess = require(path.join(buildPath, 'pre-compile')),
|
var preprocess = require(path.join(buildPath, 'pre-compile')),
|
||||||
postprocess = require(path.join(buildPath, 'post-compile'));
|
postprocess = require(path.join(buildPath, 'post-compile')),
|
||||||
|
uglifyJS = require(path.join(__dirname, 'vendor', 'uglifyjs', 'uglify-js'));
|
||||||
|
|
||||||
|
/** Used to shares values between multiple callbacks */
|
||||||
|
var accumulator = {
|
||||||
|
'compiled': {},
|
||||||
|
'uglified': {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Closure Compiler command-line options */
|
||||||
|
var closureOptions = [
|
||||||
|
'--compilation_level=ADVANCED_OPTIMIZATIONS',
|
||||||
|
'--language_in=ECMASCRIPT5_STRICT',
|
||||||
|
'--warning_level=QUIET'
|
||||||
|
];
|
||||||
|
|
||||||
|
/** Gzip command-line options */
|
||||||
|
var gzipOptions = ['-9f', '-c'];
|
||||||
|
|
||||||
/** The pre-processed Lo-Dash source */
|
/** The pre-processed Lo-Dash source */
|
||||||
var source = preprocess(fs.readFileSync(path.join(__dirname, 'lodash.js'), 'utf8'));
|
var source = preprocess(fs.readFileSync(path.join(__dirname, 'lodash.js'), 'utf8'));
|
||||||
|
|
||||||
/** Load the UglifyJS compressor */
|
|
||||||
var uglifyJS = require(path.join(__dirname, 'vendor', 'uglifyjs', 'uglify-js'));
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,10 +55,12 @@
|
|||||||
* @param {Function} callback The function to call once the process completes.
|
* @param {Function} callback The function to call once the process completes.
|
||||||
*/
|
*/
|
||||||
function invoke(name, parameters, source, encoding, callback) {
|
function invoke(name, parameters, source, encoding, callback) {
|
||||||
// the process instance and its standard output and error streams
|
// the standard error stream, standard output stream, and process instance
|
||||||
var process = spawn(name, parameters),
|
var error = '',
|
||||||
results = '', error = '';
|
output = '',
|
||||||
|
process = spawn(name, parameters);
|
||||||
|
|
||||||
|
// juggle arguments
|
||||||
if (typeof encoding == 'string' && callback != null) {
|
if (typeof encoding == 'string' && callback != null) {
|
||||||
// explicitly set the encoding of the output stream if one is specified
|
// explicitly set the encoding of the output stream if one is specified
|
||||||
process.stdout.setEncoding(encoding);
|
process.stdout.setEncoding(encoding);
|
||||||
@@ -50,24 +69,24 @@
|
|||||||
encoding = null;
|
encoding = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
process.stdout.on('data', function onData(data) {
|
process.stdout.on('data', function(data) {
|
||||||
// append the compiled source to the output stream
|
// append the data to the output stream
|
||||||
results += data;
|
output += data;
|
||||||
});
|
});
|
||||||
|
|
||||||
process.stderr.on('data', function onError(data) {
|
process.stderr.on('data', function(data) {
|
||||||
// append the error message to the error stream
|
// append the error message to the error stream
|
||||||
error += data;
|
error += data;
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on('exit', function onExit(status) {
|
process.on('exit', function(status) {
|
||||||
var exception = null;
|
var exception = null;
|
||||||
// `status` contains the process exit code
|
// `status` contains the process exit code
|
||||||
if (status) {
|
if (status) {
|
||||||
exception = new Error(error);
|
exception = new Error(error);
|
||||||
exception.status = status;
|
exception.status = status;
|
||||||
}
|
}
|
||||||
callback(exception, results);
|
callback(exception, output);
|
||||||
});
|
});
|
||||||
|
|
||||||
// proxy the standard input to the process
|
// proxy the standard input to the process
|
||||||
@@ -76,35 +95,37 @@
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
// create the destination directory if it doesn't exist
|
/**
|
||||||
if (!path.existsSync(distPath)) {
|
* Compresses a `source` string using the Closure Compiler. Yields the
|
||||||
fs.mkdirSync(distPath);
|
* minified result, and any exceptions encountered, to a `callback` function.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {String} source The JavaScript source to minify.
|
||||||
|
* @param {Function} callback The function to call once the process completes.
|
||||||
|
*/
|
||||||
|
function closureCompile(source, callback) {
|
||||||
|
console.log('Compressing lodash.js using the Closure Compiler...');
|
||||||
|
invoke('java', ['-jar', closurePath].concat(closureOptions), source, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// compress and `gzip` Lo-Dash using the Closure Compiler
|
/**
|
||||||
console.log('Compressing Lodash using the Closure Compiler...');
|
* Compresses a `source` string using UglifyJS. Yields the result to a
|
||||||
invoke('java', ['-jar', path.join(__dirname, 'vendor', 'closure-compiler', 'compiler.jar'), '--compilation_level=ADVANCED_OPTIMIZATIONS', '--language_in=ECMASCRIPT5_STRICT', '--warning_level=QUIET'], source, function onClosureCompile(exception, compiledSource) {
|
* `callback` function. This function is synchronous; the `callback` is used
|
||||||
if (exception) {
|
* for symmetry.
|
||||||
throw exception;
|
*
|
||||||
}
|
* @private
|
||||||
|
* @param {String} source The JavaScript source to minify.
|
||||||
|
* @param {Function} callback The function to call once the process completes.
|
||||||
|
*/
|
||||||
|
function uglify(source, callback) {
|
||||||
|
var exception,
|
||||||
|
result,
|
||||||
|
ugly = uglifyJS.uglify;
|
||||||
|
|
||||||
// post-process and `gzip` the compiled distribution
|
console.log('Compressing lodash.js using UglifyJS...');
|
||||||
compiledSource = postprocess(compiledSource);
|
|
||||||
invoke('gzip', ['-9f', '-c'], compiledSource, 'binary', function onClosureCompress(exception, compiledGzippedSource) {
|
|
||||||
var compiledSize, ugly, uglifiedSource;
|
|
||||||
if (exception) {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
// store and print the `gzip`-ped size of the compiled distribution
|
try {
|
||||||
compiledSize = compiledGzippedSource.length;
|
result = ugly.gen_code(
|
||||||
console.log('Done. Size: %d KB.', compiledSize);
|
|
||||||
|
|
||||||
// compress Lo-Dash using UglifyJS
|
|
||||||
console.log('Compressing Lodash using UglifyJS...');
|
|
||||||
ugly = uglifyJS.uglify;
|
|
||||||
|
|
||||||
uglifiedSource = ugly.gen_code(
|
|
||||||
// enable unsafe transformations
|
// enable unsafe transformations
|
||||||
ugly.ast_squeeze_more(
|
ugly.ast_squeeze_more(
|
||||||
ugly.ast_squeeze(
|
ugly.ast_squeeze(
|
||||||
@@ -116,35 +137,118 @@
|
|||||||
))), {
|
))), {
|
||||||
'ascii_only': true
|
'ascii_only': true
|
||||||
});
|
});
|
||||||
|
} catch(e) {
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
// lines are restricted to 500 characters for consistency with the Closure Compiler
|
||||||
|
callback(exception, result && ugly.split_lines(result, 500));
|
||||||
|
}
|
||||||
|
|
||||||
// post-process and `gzip` the uglified distribution. Lines are
|
/*--------------------------------------------------------------------------*/
|
||||||
// restricted to 500 characters for consistency with Closure Compiler
|
|
||||||
uglifiedSource = postprocess(ugly.split_lines(uglifiedSource, 500));
|
|
||||||
invoke('gzip', ['-9f', '-c'], uglifiedSource, 'binary', function onUglifyCompress(exception, uglifiedGzippedSource) {
|
|
||||||
var uglifiedSize;
|
|
||||||
if (exception) {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
// store and print the `gzip`-ped size of the uglified distribution
|
/**
|
||||||
uglifiedSize = uglifiedGzippedSource.length;
|
* The `closureCompile()` callback.
|
||||||
console.log('Done. Size: %d KB.', uglifiedSize);
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object|Undefined} exception The error object.
|
||||||
|
* @param {String} result The resulting minified source.
|
||||||
|
*/
|
||||||
|
function onClosureCompile(exception, result) {
|
||||||
|
if (exception) {
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
// store the post-processed Closure Compiler result and gzip it
|
||||||
|
accumulator.compiled.source = result = postprocess(result);
|
||||||
|
invoke('gzip', gzipOptions, result, 'binary', onClosureGzip);
|
||||||
|
}
|
||||||
|
|
||||||
// save the compiled version to disk. The explicit `binary`
|
/**
|
||||||
// encoding for the `gzip`-ped version is necessary to ensure that
|
* The Closure Compiler `gzip` callback.
|
||||||
// the stream is written correctly
|
*
|
||||||
fs.writeFileSync(path.join(distPath, 'lodash.compiler.js'), compiledSource);
|
* @private
|
||||||
fs.writeFileSync(path.join(distPath, 'lodash.compiler.js.gz'), compiledGzippedSource, 'binary');
|
* @param {Object|Undefined} exception The error object.
|
||||||
|
* @param {String} result The resulting gzipped source.
|
||||||
|
*/
|
||||||
|
function onClosureGzip(exception, result) {
|
||||||
|
if (exception) {
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
// store the gzipped result and report the size
|
||||||
|
accumulator.compiled.gzip = result;
|
||||||
|
console.log('Done. Size: %d KB.', result.length);
|
||||||
|
|
||||||
// save the uglified version to disk
|
// next, minify using UglifyJS
|
||||||
fs.writeFileSync(path.join(distPath, 'lodash.uglify.js'), uglifiedSource);
|
uglify(source, onUglify);
|
||||||
fs.writeFileSync(path.join(distPath, 'lodash.uglify.js.gz'), uglifiedGzippedSource, 'binary');
|
}
|
||||||
|
|
||||||
// select the smallest minified distribution and use it as the
|
/**
|
||||||
// official minified release. If they are equivalent, the compiled
|
* The `uglify()` callback.
|
||||||
// distribution is used
|
*
|
||||||
fs.writeFileSync(path.join(__dirname, 'lodash.min.js'), compiledSize < uglifiedSize ? compiledSource : uglifiedSource);
|
* @private
|
||||||
});
|
* @param {Object|Undefined} exception The error object.
|
||||||
});
|
* @param {String} result The resulting minified source.
|
||||||
});
|
*/
|
||||||
|
function onUglify(exception, result) {
|
||||||
|
if (exception) {
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
// store the post-processed Uglified result and gzip it
|
||||||
|
accumulator.uglified.source = postprocess(result);
|
||||||
|
invoke('gzip', gzipOptions, result, 'binary', onUglifyGzip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The UglifyJS `gzip` callback.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object|Undefined} exception The error object.
|
||||||
|
* @param {String} result The resulting gzipped source.
|
||||||
|
*/
|
||||||
|
function onUglifyGzip(exception, result) {
|
||||||
|
if (exception) {
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
// store the gzipped result and report the size
|
||||||
|
accumulator.uglified.gzip = result;
|
||||||
|
console.log('Done. Size: %d KB.', result.length);
|
||||||
|
|
||||||
|
// finish by choosing the smallest compressed file
|
||||||
|
onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The callback executed after JavaScript source is minified and gzipped.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function onComplete() {
|
||||||
|
var compiled = accumulator.compiled,
|
||||||
|
uglified = accumulator.uglified;
|
||||||
|
|
||||||
|
// save the Closure Compiled version to disk
|
||||||
|
fs.writeFileSync(path.join(distPath, 'lodash.compiler.js'), compiled.source);
|
||||||
|
// explicit 'binary' is necessary to ensure the stream is written correctly
|
||||||
|
fs.writeFileSync(path.join(distPath, 'lodash.compiler.js.gz'), compiled.gzip, 'binary');
|
||||||
|
|
||||||
|
// save the Uglified version to disk
|
||||||
|
fs.writeFileSync(path.join(distPath, 'lodash.uglify.js'), uglified.source);
|
||||||
|
fs.writeFileSync(path.join(distPath, 'lodash.uglify.js.gz'), uglified.gzip, 'binary');
|
||||||
|
|
||||||
|
// select the smallest gzipped file and use its minified form as the
|
||||||
|
// official minified release (ties go to Closure Compiler)
|
||||||
|
fs.writeFileSync(path.join(__dirname, 'lodash.min.js'),
|
||||||
|
uglified.gzip.length < compiled.gzip.length
|
||||||
|
? uglified.source
|
||||||
|
: compiled.source
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// create the destination directory if it doesn't exist
|
||||||
|
if (!path.existsSync(distPath)) {
|
||||||
|
fs.mkdirSync(distPath);
|
||||||
|
}
|
||||||
|
// begin the minification process
|
||||||
|
closureCompile(source, onClosureCompile);
|
||||||
}());
|
}());
|
||||||
|
|||||||
@@ -245,7 +245,7 @@
|
|||||||
options = {},
|
options = {},
|
||||||
props = ['beforeLoop', 'loopExp', 'inLoop', 'afterLoop'];
|
props = ['beforeLoop', 'loopExp', 'inLoop', 'afterLoop'];
|
||||||
|
|
||||||
// use a while-loop to merge options because `extend` isn't defined yet
|
// use simple loops to merge options because `extend` isn't defined yet
|
||||||
while (++index < arguments.length) {
|
while (++index < arguments.length) {
|
||||||
for (prop in arguments[index]) {
|
for (prop in arguments[index]) {
|
||||||
options[prop] = arguments[index][prop];
|
options[prop] = arguments[index][prop];
|
||||||
|
|||||||
Reference in New Issue
Block a user