Skip to content

Commit

Permalink
Decoupled buildCSSBundles to css.buildBundles
Browse files Browse the repository at this point in the history
  • Loading branch information
gseguin committed Apr 10, 2014
1 parent 51caad9 commit 4b4a4cd
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 193 deletions.
194 changes: 194 additions & 0 deletions lib/css.js
@@ -0,0 +1,194 @@
"use strict";

var _ = require( 'underscore' ),
applyFilter = require( './filter' ).apply,
async = require( "async" ),
cssConcat = require( 'css-concat' ),
dependencies = require( "./dependencies" ),
fs = require( "fs" ),
logger = require( 'simple-log' ).init( 'amd-builder:css' ),
path = require( 'path' ),
Promise = require( "node-promise" ).Promise,
requirejs = require( 'requirejs' ),
redefineRequireJSLogging = require( "./requirejs-utils" ).redefineRequireJSLogging;


function buildBundles( baseName, workspaceDir, relBaseUrl, compiledDir, files, filter, optimize ) {
// logger.log( "buildCSSBundle()" );
var promise = new Promise(),
baseOut = path.join( compiledDir, baseName );

// get the dependency map for all modules
dependencies.buildMap( workspaceDir, relBaseUrl, compiledDir, files ).then(
function( modules ) {
var absBaseUrl = path.normalize( path.join( workspaceDir, relBaseUrl ) );
var cssFiles = {
default: []
},
contents = {
default: ""
},
outputFiles = [];

async.waterfall([
function( next ) {
var name,
processed = {},
addCssDependencies = function( m ) {
processed[ m ] = true;
if ( !processed[ m ] && modules[ m ] && modules[ m ].deps ) {
modules[ m ].deps.forEach( addCssDependencies );
}
if ( modules[ m ] && modules[ m ].css ) {
if ( typeof( modules[ m ].css ) === "string" ) {
// logger.log( "Adding: " + modules[ m ].css );
cssFiles.default = _.union( cssFiles.default, modules[ m ].css.split( "," ) );
} else {
for ( name in modules[ m ].css ) {
if ( modules[ m ].css.hasOwnProperty( name ) ) {
cssFiles[ name ] = cssFiles[ name ] || [];
// logger.log( "Adding css." + name + ": " + modules[ m ].css[ name ]);
cssFiles[ name ] = _.union( cssFiles[ name ], modules[ m ].css[ name ].split( "," ) );
}
}
}
}
};

files.forEach( addCssDependencies );
next();
},
function( next ) {
var keys = Object.keys( cssFiles );

keys.forEach( function( name ) {
if ( cssFiles.hasOwnProperty( name ) ) {
// resolve the file paths
cssFiles[ name ] = _.uniq( cssFiles[ name ]).map( function( s ) {
return path.resolve( absBaseUrl, s.trim() );
});

contents[ name ] = "";
cssFiles[ name ].forEach( function( file ) {
contents[ name ] += "\n";
try {
contents[ name ] += cssConcat.concat( file, { comments: false });
} catch ( e ) {
next( e.toString() );
}
});
contents[ name ] = contents[ name ].trim();
if ( contents[ name ].length === 0 ) {
if ( optimize ) {
logger.log( name, "CSS file is empty, removing it from optimized bundle" );
} else {
logger.log( name, "CSS file is empty, removing it from bundle" );
}
delete contents[ name ];
delete cssFiles[ name ];
}
}
});
next();
},
function( next ) {
async.forEach(
Object.keys( contents ),
function( key, callback ) {
var unoptimizedOut = baseOut + ( key === "default" ? "" : ( "." + key ) ) + ".css";

async.waterfall([
function( step ) {
applyFilter( absBaseUrl, filter, contents[ key ], ".css", step );
},
function( content, step ) {
fs.writeFile( unoptimizedOut, content, 'utf8', step );
},
function( step ) {
if ( !optimize ) {
outputFiles.push( unoptimizedOut );
}
step();
}
], callback );

},
next
);
},
function( next ) {
async.forEach(
Object.keys( contents ),
function( key, callback ) {
var unoptimizedOut = baseOut + ( key === "default" ? "" : ( "." + key ) ) + ".css",
optimizedOut = baseOut + ( key === "default" ? "" : ( "." + key ) ) + ".min.css";

try {
process.chdir( workspaceDir );
}
catch ( e1 ) {
next( e1.toString() );
}

redefineRequireJSLogging();

try {
requirejs.optimize(
{
cssIn: unoptimizedOut,
out: optimizedOut,
optimizeCss: "standard",
logLevel: 4 // SILENT
},
function( response ) {
async.waterfall([
function( step ) {
fs.readFile( optimizedOut, "utf-8", step );
},
function( content, step ) {
applyFilter( absBaseUrl, filter, content, ".min.css", step );
},
function( content, step ) {
fs.writeFile( optimizedOut, content, 'utf8', step );
},
function( step ) {
if ( optimize ) {
outputFiles.push( optimizedOut );
}
step();
}
], callback );
},
function( err ) {
// We're expecting a string as the error.
next( err.message );
}
);
} catch ( e2 ) {
next( e2.toString() );
}
},
next
);
}
], function( err ) {
if ( err ) {
logger.error( err );
promise.reject( err );
} else {
if ( outputFiles.length === 0 || outputFiles.length > 1 ) {
promise.resolve( outputFiles );
} else {
promise.resolve( outputFiles[ 0 ]);
}
}
});
},
function( err ) {
promise.reject( err );
}
);
return promise;
}

exports.buildBundles = buildBundles;
8 changes: 4 additions & 4 deletions lib/dependencies.js
Expand Up @@ -25,7 +25,7 @@ function getFiles( dir, pattern, mapFn, callback ) {
], callback);
};

function buildMap( workspaceDir, compileDir, baseUrl, include ) {
function buildMap( workspaceDir, baseUrl, compiledDir, include ) {
var id = bid++;
// logger.log( "buildMap["+id+"]()" );
var promise = new Promise(),
Expand All @@ -40,7 +40,7 @@ function buildMap( workspaceDir, compileDir, baseUrl, include ) {
// logger.log( "buildMap["+id+"](): step 1" );
// If no name is provided, scan the baseUrl for js files and return the dep map for all JS objects in baseUrl
if ( include && include.length > 0 ) {
next();
next( null, null );
} else {
getFiles(
baseUrl,
Expand All @@ -60,7 +60,7 @@ function buildMap( workspaceDir, compileDir, baseUrl, include ) {
// Generate a sha on the sorted names
var digest = shasum.update( include.join( "," ) ).digest( "hex" );

filename += path.join( compileDir, "deps-" + digest + ".json" );
filename += path.join( compiledDir, "deps-" + digest + ".json" );

fs.exists( filename, function( exists ) {
next( null, digest, exists )
Expand All @@ -82,7 +82,7 @@ function buildMap( workspaceDir, compileDir, baseUrl, include ) {
async.waterfall([
function( cb ) {
// logger.log( "buildMap["+id+"](): step 3.1" );
fs.mkdir( compileDir, function( err ) {
fs.mkdir( compiledDir, function( err ) {
if ( err && err.code != "EEXIST" ) {
cb( err );
} else {
Expand Down
13 changes: 13 additions & 0 deletions lib/filter.js
@@ -0,0 +1,13 @@
"use strict";

var path = require( "path" );

function apply( baseUrl, filter, contents, ext, callback ) {
if ( filter ) {
require( path.join( baseUrl, filter ) )( contents, ext, callback );
} else {
callback( null, contents );
}
}

exports.apply = apply;

0 comments on commit 4b4a4cd

Please sign in to comment.