Permalink
Browse files

Refactor assets processor

  • Loading branch information...
1 parent 9204928 commit ce918b576a0373d4a2df661316b19ef37e023fac @ixti ixti committed Jun 19, 2012
Showing with 183 additions and 78 deletions.
  1. +1 −0 .gitignore
  2. +1 −0 .jshintignore
  3. +2 −78 lib/ndoc/renderers/html.js
  4. +76 −0 lib/ndoc/renderers/html/assets.js
  5. +103 −0 lib/ndoc/renderers/html/assets/compression.js
View
@@ -3,3 +3,4 @@ doc
playground*
tests/prototype-doc
tests/features-doc
+.cache/
View
@@ -6,3 +6,4 @@ tests/
skins/
lib/ndoc/renderers/html/
lib/ndoc/parsers/javascript.js
+.cache/
View
@@ -11,16 +11,13 @@ var pathExists = fs.exists || path.exists;
// 3rd-party
var FsTools = require('fs-tools');
-var Mincer = require('mincer');
-var UglifyJS = require('uglify-js');
-var Csso = require('csso');
var Jade = require('jade');
var md2html = require('marked');
-var Stylus = require('stylus');
// internal
var extend = require('../common').extend;
+var assets = require('./html/assets');
////////////////////////////////////////////////////////////////////////////////
@@ -83,79 +80,6 @@ module.exports.args = [
];
-function prepare_mincer(templatePath, callback) {
- var files, environment;
-
- environment = new Mincer.Environment(templatePath);
- files = ['main.js', 'main.css', 'modernizr.js'];
-
-
- // function that matches any non-js or non-css files
- files.push(function nonAsset(logicalPath) {
- var extname = path.extname(logicalPath);
- return (!/\.(js|css)$/.test(extname));
- });
-
-
- environment.appendPath('assets/javascripts');
- environment.appendPath('assets/stylesheets');
- environment.appendPath('assets/images');
-
-
- Mincer.StylusEngine.registerConfigurator(function (style) {
- style.define('url', Stylus.url());
- });
-
-
- if ('development' !== process.env.NODE_ENV) {
- // Register compressors
- environment.jsCompressor = function (data, callback) {
- try {
- var ast = UglifyJS.parser.parse(data);
-
- ast = UglifyJS.uglify.ast_mangle(ast);
- ast = UglifyJS.uglify.ast_squeeze(ast);
-
- callback(null, UglifyJS.uglify.gen_code(ast));
- } catch (err) {
- callback(err);
- }
- };
-
- environment.cssCompressor = function (data, callback) {
- try {
- callback(null, Csso.justDoIt(data));
- } catch (err) {
- callback(err);
- }
- };
- }
-
-
- // Configure logger
- // FIXME: Replace with NDoc's logger
- Mincer.logger.use(console);
-
-
- // Returns plain array of filenames matching `filters`
- function get_assets(filters) {
- var result = [];
-
- environment.eachLogicalPath(filters, function (logicalPath) {
- result.push(logicalPath);
- });
-
- return result;
- }
-
-
- // Precompile all assets
- environment.precompile(get_assets(files), function (err) {
- callback(err, environment);
- });
-}
-
-
module.exports.render = function (ndoc, options, callback) {
var file, str, fn, packageJson, list, id, obj;
@@ -356,7 +280,7 @@ module.exports.render = function (ndoc, options, callback) {
return r;
}
- prepare_mincer(options.htmlSkin, function (err, env) {
+ assets.prepare(options.htmlSkin, function (err, env) {
var vars, html;
if (err) {
@@ -0,0 +1,76 @@
+"use strict";
+
+
+/*global nodeca, _*/
+
+
+// stdlib
+var fs = require('fs');
+var path = require('path');
+
+
+// 3rd-party
+var Mincer = require('mincer');
+var stylus = require('stylus');
+
+
+// internal
+var compression = require('./assets/compression');
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+// Returns plain array of filenames matching `filters`
+function get_assets(env, filters) {
+ var result = [];
+
+ env.eachLogicalPath(filters, function (logicalPath) {
+ result.push(logicalPath);
+ });
+
+ return result;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+module.exports.prepare = function prepare(templatePath, callback) {
+ var files, environment;
+
+ environment = new Mincer.Environment(templatePath);
+ files = ['main.js', 'main.css', 'modernizr.js'];
+
+ // function that matches any non-js or non-css files
+ files.push(function nonAsset(logicalPath) {
+ var extname = path.extname(logicalPath);
+ return (!/\.(js|css)$/.test(extname));
+ });
+
+
+ environment.appendPath('assets/javascripts');
+ environment.appendPath('assets/stylesheets');
+ environment.appendPath('assets/images');
+
+
+ Mincer.StylusEngine.registerConfigurator(function (style) {
+ style.define('url', stylus.url());
+ });
+
+
+ // set up compressors
+ environment.jsCompressor = compression.js;
+ environment.cssCompressor = compression.css;
+
+
+ // Configure logger
+ // FIXME: Replace with NDoc's logger
+ Mincer.logger.use(console);
+
+
+ // Precompile all assets
+ environment.precompile(get_assets(environment, files), function (err) {
+ callback(err, environment);
+ });
+};
@@ -0,0 +1,103 @@
+"use strict";
+
+
+/*global nodeca, _*/
+
+
+// stdlib
+var fs = require('fs');
+var path = require('path');
+var crypto = require('crypto');
+
+
+// 3rd-party
+var Mincer = require('mincer');
+var uglify = require('uglify-js');
+var Csso = require('csso');
+var FsTools = require('fs-tools');
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+var CACHE_DIR = path.resolve(__dirname, '.cache');
+var SALT = JSON.stringify(require('../../../../../package.json'));
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+function hash(str) {
+ return crypto.createHash('md5').update(str).digest('hex');
+}
+
+
+function get_cache(key) {
+ var base = CACHE_DIR + '/' + key,
+ cached = {};
+
+ if (path.existsSync(base + '.data')) {
+ cached.data = fs.readFileSync(base + '.data', 'utf8');
+ }
+
+ if (path.existsSync(base + '.digest')) {
+ cached.digest = fs.readFileSync(base + '.digest', 'utf8');
+ }
+
+ return cached;
+}
+
+
+function set_cache(key, digest, data, callback) {
+ var base = CACHE_DIR + '/' + key;
+
+ FsTools.mkdir(CACHE_DIR, function (err) {
+ if (err) {
+ callback(err);
+ return;
+ }
+
+ try {
+ fs.writeFileSync(base + '.data', data, 'utf8');
+ fs.writeFileSync(base + '.digest', digest, 'utf8');
+ } catch (err) {
+ callback(err);
+ return;
+ }
+
+ callback();
+ });
+}
+
+
+function cachable(compressor) {
+ return function (context, data, callback) {
+ var key = hash(context.logicalPath + context.contentType),
+ digest = hash(data + SALT),
+ cached = get_cache(key),
+ compressed;
+
+ if (cached.digest === digest) {
+ callback(null, cached.data);
+ return;
+ }
+
+ try {
+ compressed = compressor(data);
+ } catch (err) {
+ callback(err);
+ return;
+ }
+
+ set_cache(key, digest, compressed, function (err) {
+ callback(err, compressed);
+ });
+ };
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+module.exports.js = cachable(uglify);
+module.exports.css = cachable(Csso.justDoIt);

0 comments on commit ce918b5

Please sign in to comment.