Skip to content
Browse files

Defer downloading required minifies until the `lodash` command-line e…

…xecutable is used for the first time.
  • Loading branch information...
1 parent 49d4727 commit 9260f3e6d2006ea279f6c4dcec27d4f38ab88600 @jdalton jdalton committed
Showing with 141 additions and 152 deletions.
  1. +140 −15 build/minify.js
  2. +0 −135 build/post-install.js
  3. +1 −2 package.json
View
155 build/minify.js
@@ -2,26 +2,56 @@
;(function() {
'use strict';
- /** The Node filesystem, path, `zlib`, and child process modules */
+ /** Load Node modules */
var fs = require('fs'),
- gzip = require('zlib').gzip,
+ https = require('https'),
path = require('path'),
- spawn = require('child_process').spawn;
+ spawn = require('child_process').spawn,
+ tar = require('../vendor/tar/tar.js'),
+ zlib = require('zlib');
+
+ /** Load other modules */
+ var preprocess = require('./pre-compile.js'),
+ postprocess = require('./post-compile.js');
+
+ /** The Git object ID of `closure-compiler.tar.gz` */
+ var closureId = 'a2787b470c577cee2404d186c562dd9835f779f5';
+
+ /** The Git object ID of `uglifyjs.tar.gz` */
+ var uglifyId = '505f1be36ef60fd25a992a522f116d5179ab317f';
/** The path of the directory that is the base of the repository */
var basePath = fs.realpathSync(path.join(__dirname, '..'));
- /** The path of the directory where the Closure Compiler is located */
- var closurePath = path.join(basePath, 'vendor', 'closure-compiler', 'compiler.jar');
+ /** The path of the `vendor` directory */
+ var vendorPath = path.join(basePath, 'vendor');
- /** Load other modules */
- var preprocess = require('./pre-compile.js'),
- postprocess = require('./post-compile.js'),
- uglifyJS = require('../vendor/uglifyjs/tools/node.js');
+ /** The path to the Closure Compiler `.jar` */
+ var closurePath = path.join(vendorPath, 'closure-compiler', 'compiler.jar');
+
+ /** The path to the UglifyJS module */
+ var uglifyPath = path.join(vendorPath, 'uglifyjs', 'tools', 'node.js');
/** The Closure Compiler command-line options */
var closureOptions = ['--warning_level=QUIET'];
+ /** The media type for raw blob data */
+ var mediaType = 'application/vnd.github.v3.raw';
+
+ /** Used to reference parts of the blob href */
+ var location = (function() {
+ var host = 'api.github.com',
+ origin = 'https://api.github.com',
+ pathname = '/repos/bestiejs/lodash/git/blobs';
+
+ return {
+ 'host': host,
+ 'href': origin + pathname,
+ 'origin': origin,
+ 'pathname': pathname
+ };
+ }());
+
/** The Closure Compiler optimization modes */
var optimizationModes = {
'simple': 'SIMPLE_OPTIMIZATIONS',
@@ -79,7 +109,30 @@
source = fs.readFileSync(filePath, 'utf8');
}
- new Minify(source, options);
+ // fetch the Closure Compiler
+ getDependency({
+ 'id': 'closure-compiler',
+ 'hashId': closureId,
+ 'path': vendorPath,
+ 'title': 'the Closure Compiler',
+ 'onComplete': function(exception) {
+ var error = exception;
+
+ // fetch UglifyJS
+ getDependency({
+ 'id': 'uglifyjs',
+ 'hashId': uglifyId,
+ 'title': 'UglifyJS',
+ 'path': vendorPath,
+ 'onComplete': function(exception) {
+ error || (error = exception);
+ if (!error) {
+ new Minify(source, options);
+ }
+ }
+ });
+ }
+ });
}
/**
@@ -122,6 +175,76 @@
/*--------------------------------------------------------------------------*/
/**
+ * Fetches a required `.tar.gz` dependency with the given Git object ID from
+ * the Lo-Dash repo on GitHub. The object ID may be obtained by running
+ * `git hash-object path/to/dependency.tar.gz`.
+ *
+ * @private
+ * @param {Object} options The options object.
+ * id - The Git object ID of the `.tar.gz` file.
+ * onComplete - The function, invoked with one argument (exception),
+ * called once the extraction has finished.
+ * path - The path of the extraction directory.
+ * title - The dependency's title used in status updates logged to the console.
+ */
+ function getDependency(options) {
+ options || (options = {});
+
+ var ran,
+ destPath = options.path,
+ hashId = options.hashId,
+ id = options.id,
+ onComplete = options.onComplete,
+ title = options.title;
+
+ // exit early if dependency exists
+ if (fs.existsSync(path.join(destPath, id))) {
+ onComplete();
+ return;
+ }
+ var callback = function(exception) {
+ if (ran) {
+ return;
+ }
+ if (exception) {
+ console.error([
+ 'There was a problem installing ' + title + '.',
+ 'Try running the command as root, via `sudo`, or manually install by running:',
+ '',
+ "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + hashId + " | tar xvz -C '" + destPath + "'",
+ ''
+ ].join('\n'));
+ }
+ ran = true;
+ process.removeListener('uncaughtException', callback);
+ onComplete(exception);
+ };
+
+ console.log('Downloading ' + title + '...');
+ process.on('uncaughtException', callback);
+
+ https.get({
+ 'host': location.host,
+ 'path': location.pathname + '/' + hashId,
+ 'headers': {
+ // By default, all GitHub blob API endpoints return a JSON document
+ // containing Base64-encoded blob data. Overriding the `Accept` header
+ // with the GitHub raw media type returns the blob data directly.
+ // See http://developer.github.com/v3/media/.
+ 'Accept': mediaType
+ }
+ }, function(response) {
+ var decompressor = zlib.createUnzip(),
+ parser = new tar.Extract({ 'path': destPath });
+
+ parser.on('end', callback);
+ response.pipe(decompressor).pipe(parser);
+ });
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
* Compresses a `source` string using the Closure Compiler. Yields the
* minified result, and any exceptions encountered, to a `callback` function.
*
@@ -181,6 +304,8 @@
console.log('Compressing ' + path.basename(this.outputPath, '.js') + ' using ' + label + '...');
}
try {
+ var uglifyJS = require(uglifyPath);
+
// 1. parse
var toplevel = uglifyJS.parse(source);
@@ -232,7 +357,7 @@
}
result = postprocess(result);
this.compiled.simple.source = result;
- gzip(result, onClosureSimpleGzip.bind(this));
+ zlib.gzip(result, onClosureSimpleGzip.bind(this));
}
/**
@@ -268,7 +393,7 @@
}
result = postprocess(result);
this.compiled.advanced.source = result;
- gzip(result, onClosureAdvancedGzip.bind(this));
+ zlib.gzip(result, onClosureAdvancedGzip.bind(this));
}
/**
@@ -304,7 +429,7 @@
}
result = postprocess(result);
this.uglified.source = result;
- gzip(result, onUglifyGzip.bind(this));
+ zlib.gzip(result, onUglifyGzip.bind(this));
}
/**
@@ -340,7 +465,7 @@
}
result = postprocess(result);
this.hybrid.simple.source = result;
- gzip(result, onSimpleHybridGzip.bind(this));
+ zlib.gzip(result, onSimpleHybridGzip.bind(this));
}
/**
@@ -376,7 +501,7 @@
}
result = postprocess(result);
this.hybrid.advanced.source = result;
- gzip(result, onAdvancedHybridGzip.bind(this));
+ zlib.gzip(result, onAdvancedHybridGzip.bind(this));
}
/**
View
135 build/post-install.js
@@ -1,135 +0,0 @@
-#!/usr/bin/env node
-;(function() {
- 'use strict';
-
- /** Load Node modules */
- var fs = require('fs'),
- path = require('path');
-
- /** The path of the directory that is the base of the repository */
- var basePath = fs.realpathSync(path.join(__dirname, '..'));
-
- /** The path of the `vendor` directory */
- var vendorPath = path.join(basePath, 'vendor');
-
- /** The Git object ID of `closure-compiler.tar.gz` */
- var closureId = 'a2787b470c577cee2404d186c562dd9835f779f5';
-
- /** The Git object ID of `uglifyjs.tar.gz` */
- var uglifyId = '505f1be36ef60fd25a992a522f116d5179ab317f';
-
- /** The media type for raw blob data */
- var mediaType = 'application/vnd.github.v3.raw';
-
- /** Used to reference parts of the blob href */
- var location = (function() {
- var host = 'api.github.com',
- origin = 'https://api.github.com',
- pathname = '/repos/bestiejs/lodash/git/blobs';
-
- return {
- 'host': host,
- 'href': origin + pathname,
- 'origin': origin,
- 'pathname': pathname
- };
- }());
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Fetches a required `.tar.gz` dependency with the given Git object ID from
- * the Lo-Dash repo on GitHub. The object ID may be obtained by running
- * `git hash-object path/to/dependency.tar.gz`.
- *
- * @private
- * @param {Object} options The options object.
- * id - The Git object ID of the `.tar.gz` file.
- * onComplete - The function, invoked with one argument (exception),
- * called once the extraction has finished.
- * path - The path of the extraction directory.
- * title - The dependency's title used in status updates logged to the console.
- */
- function getDependency(options) {
- options || (options = {});
-
- var id = options.id,
- onComplete = options.onComplete,
- path = options.path,
- title = options.title;
-
- function callback(exception) {
- if (exception) {
- console.error([
- 'There was a problem installing ' + title + '. To manually install, run:',
- '',
- "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + id + " | tar xvz -C '" + path + "'"
- ].join('\n'));
- }
- onComplete(exception);
- }
-
- console.log('Downloading ' + title + '...');
-
- https.get({
- 'host': location.host,
- 'path': location.pathname + '/' + id,
- 'headers': {
- // By default, all GitHub blob API endpoints return a JSON document
- // containing Base64-encoded blob data. Overriding the `Accept` header
- // with the GitHub raw media type returns the blob data directly.
- // See http://developer.github.com/v3/media/.
- 'Accept': mediaType
- }
- }, function(response) {
- var decompressor = zlib.createUnzip(),
- parser = new tar.Extract({ 'path': path });
-
- decompressor.on('error', callback);
- parser.on('end', callback).on('error', callback);
- response.pipe(decompressor).pipe(parser);
- })
- .on('error', callback);
- }
-
- /*--------------------------------------------------------------------------*/
-
- if (process.env.npm_config_global === 'true') {
- // catch module load errors
- try {
- var https = require('https'),
- tar = require('../vendor/tar/tar.js'),
- zlib = require('zlib');
-
- // download the Closure Compiler
- getDependency({
- 'title': 'the Closure Compiler',
- 'id': closureId,
- 'path': vendorPath,
- 'onComplete': function() {
- // download UglifyJS
- getDependency({
- 'title': 'UglifyJS',
- 'id': uglifyId,
- 'path': vendorPath,
- 'onComplete': function() {
- process.exit();
- }
- });
- }
- });
- } catch(e) {
- console.log([
- 'Oops! There was a problem installing dependencies required by the Lo-Dash',
- 'command-line executable. To manually install UglifyJS and the Closure Compiler',
- 'run:',
- '',
- "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + closureId + " | tar xvz -C '" + vendorPath + "'",
- "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + uglifyId + " | tar xvz -C '" + vendorPath + "'",
- ''
- ].join('\n'));
-
- console.log(e);
- }
- }
-}());
View
3 package.json
@@ -47,7 +47,6 @@
},
"scripts": {
"build": "node ./build.js",
- "test": "node ./test/test.js && node ./test/test-build.js",
- "install": "node ./build/post-install.js"
+ "test": "node ./test/test.js && node ./test/test-build.js"
}
}

0 comments on commit 9260f3e

Please sign in to comment.
Something went wrong with that request. Please try again.